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 scenario: it reads the same deployed version as public chat.
-
Open the scenario 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 when you publish — together with the graph, from one button. While you are editing, the channel is marked as waiting to be published and the Publish button becomes active.
Support assistant
Widget
Recolours the whole panel and the button.
Empty — “Chat”.
Empty — icon only.
0 opens it with the page.
Empty falls back to the link's greeting.
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), plus the widget’s own greeting — separate from the hosted link’s. After editing, press the same publish button as in step 1 (Deploy version 2 — your version number will differ).
Open automatically is off by default, and deliberately so: a window nobody asked for spoils the impression of the site the visitor actually came for. Turn it on and Seconds before it opens appears beside it: 0 opens the panel with the page, any other number gives the visitor that long with the page to themselves. It opens once, and never for someone who has already pressed the button.
Allow attachments is a separate switch, also off by default. Turn it on if the bot should accept photos, voice messages and documents: a paperclip appears in the panel, and a file can simply be dropped onto the chat. The setting is shared with the hosted chat link — one conversation with two doors. Images, audio, PDF (up to 8 MB) and text files are accepted; they take room in your storage and ride the context of every later turn. A PDF reaches a model with document input; on any other the turn stops with an error.
The “Powered by iterna.ai” line in the chat panel is removed with the white-label setting, which is available from the Pro plan up.
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 scenario’s token is already filled in.
Bubble — a floating button in the corner of the page:
<script src="https://app.example.com/widget/iterna-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="iterna-chat"></div>
<script src="https://app.example.com/widget/iterna-widget.js"
data-token="<your public token>" data-mode="inline" data-target="#iterna-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 scenario. 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 scenario 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 scenario'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 scenario setting, otherwise right |
| data-accent | Accent colour | The scenario setting |
| data-title | Panel title | The scenario setting, otherwise “Chat” |
| data-launcher-text | Caption on the button | The scenario setting, otherwise icon only |
| data-launcher-icon | Button icon (emoji) | The scenario setting, otherwise a message glyph |
| data-auto-open | true — open the panel immediately | The scenario 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 Conversations section shows the list of sessions for the selected scenario 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 [iterna-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="iterna-chat"></div> comes ABOVE the script tag and that the selector matches |
| The widget is there but reports a run error | The scenario 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 | Quarks 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 |