Lesson 2. A bot on your own site
Lesson 1 ended with a public link to the chat. A link has to be sent to someone — the widget instead puts the same bot right on your page: a button in the corner or a block inside your layout.
What you end up with: a single <script> line in your site’s HTML. A visitor sees a chat
button, clicks it and talks to the same bot as through the link from lesson 1. Nothing in the
graph has to be rewritten — it is the same deployment and the same token.
Step 1. Make sure the bot is deployed
The widget is not deployed separately from the workflow: it reads the same deployed version as public chat.
-
Open the workflow from lesson 1 and go to the Deploy tab.
-
In the channel list on the left, turn on the toggle for the Widget channel and press Deploy version 1 (the version number is yours).
-
If the bot from lesson 1 is already deployed to the Public chat channel, you do not have to deploy again: the token is shared, and the widget already works with it. Turning on the Widget channel matters so that the channel is honestly shown as deployed, and so that public chat can later be switched off without switching off the widget.
Step 2. Set up the appearance
Widget settings live in the same channel and take effect as soon as they are saved, without deploying again: they are properties of the workflow, not of a graph version. The graph is the opposite — only on deploy.
Support assistant
Widget
Recolours the whole panel and the button.
Empty — “Chat”.
Empty — icon only.
What you can set: Accent, Position (left or right), Panel title, Launcher text and the button’s Icon, Open automatically and Allowed domains (one per line). After editing, press Save widget settings.
The “Powered by Flow” line in the chat panel can only be removed with the white-label setting, and that one is not available on the free plan.
Step 3. Copy the embed snippet
At the bottom of the same channel there is an Embed snippet block with a Bubble / Inline switch and a Copy button. Your workflow’s token is already filled in.
Bubble — a floating button in the corner of the page:
<script src="https://app.example.com/widget/flow-widget.js"
data-token="<your public token>" data-mode="bubble" async></script>
Inline — the chat is rendered inside your own block, with no button:
<div id="flow-chat"></div>
<script src="https://app.example.com/widget/flow-widget.js"
data-token="<your public token>" data-mode="inline" data-target="#flow-chat" async></script>
Under Settings → Widget you will find the
same tag, but with a <PUBLIC_TOKEN> placeholder instead of a token: that page is shared across
the whole workspace, while the token belongs to a specific workflow. The signing secret lives
there too; it is only needed for authenticated visitors (see
“Embeddable widget”).
Step 4. Put the tag on your page
Paste the copied line right before the closing </body> of your site. Nothing else has to be
included: the widget takes the API address from the address of the script itself, and the
appearance from the workflow settings it requests on load.
The chat is mounted into an isolated Shadow DOM. That means your site’s styles do not affect the widget, and the widget’s styles do not affect your site, even if your global CSS is aggressive.
Step 5. Check it on your own page
Open the page in a normal browser — not in the editor. The button appears in the bottom-right corner (or the left one, if configured that way), a click opens the panel, and the first message starts a session.
data-* attributes
Everything except the token is optional: values are taken from the widget settings on the server, and an attribute in the tag overrides the server value. That way the same setting can differ on two pages of your site.
| Attribute | What it sets | If omitted |
|---|---|---|
| data-token | The workflow's public token. Required | The widget does not appear at all; a warning is printed in the browser console |
| data-mode | bubble (button) or inline (block) | bubble |
| data-target | CSS selector of the container for inline mode | Inline mode does not mount; a warning in the console |
| data-height | Height of the inline panel | 560px |
| data-position | left or right | The workflow setting, otherwise right |
| data-accent | Accent colour | The workflow setting |
| data-title | Panel title | The workflow setting, otherwise “Chat” |
| data-launcher-text | Caption on the button | The workflow setting, otherwise icon only |
| data-launcher-icon | Button icon (emoji) | The workflow setting, otherwise a message glyph |
| data-auto-open | true — open the panel immediately | The workflow setting |
| data-lang | ru or en | The visitor's browser language, otherwise Russian |
| data-user-jwt | Signed visitor token, if your site knows who they are | The conversation is anonymous |
Domain restriction
The Allowed domains (one per line) field is a list of origins the widget is allowed to
work from. Empty means “any domain”. The browser’s Origin header is checked when a session
starts and when a message is sent; a foreign domain gets the line “This chat is not authorised on
this domain” in the panel.
This is a soft protection: the header is set by the browser, and a request that does not come from a browser does not set it at all. The real limiter is still the token itself — anyone who has seen it can write to the bot, and the runs are billed to the workspace owner. Treat the token as something published, not as a secret.
Where to read the conversations
Visitor conversations are not lost: the Clients section shows the list of sessions for the selected workflow and the full conversation for each one. Details are in “Clients”. The technical details of a run (which node returned what, how much it cost) are in “Runs”.
If it did not work
| What you see | Why | What to do |
|---|---|---|
| No widget on the page at all | The tag is in the wrong place or has no token: without data-token the widget stops and writes a warning to the browser console | Open the console (F12) — messages are tagged [flow-widget]. Put the tag before </body> and copy it from the “Widget” channel instead of typing it by hand |
| With inline mode nothing appeared at all — no panel, no bubble | data-mode="inline" without a valid data-target: there is no container with that selector on the page, so the loader aborts without inserting anything (it leaves a warning in the console) | Check that <div id="flow-chat"></div> comes ABOVE the script tag and that the selector matches |
| The widget is there but reports a run error | The workflow is not deployed, or the deployment was removed | The “Deploy” tab → turn the channel on → “Deploy version N” |
| “This chat is not authorised on this domain” | The page's domain is not in the allowed list | Add the whole origin, including the scheme: https://example.com. Or clear the field to allow any domain |
| Sending a message fails | Credits ran out (on the free plan work beyond the balance is not allowed) | Settings → Usage |
| It looks like the site's layout broke | The widget has nothing to do with it: it lives in an isolated Shadow DOM, its CSS does not leak out | Look for the cause in your own page; test the hypothesis by removing the tag for a minute |
| A visitor cannot attach a file | That is correct: there is no anonymous upload in the product | Put the materials for answers into the knowledge base yourself |