Embed the website widget
Copy one script tag from Integrations → Web widget, paste it on your published pages, then allow your domain and verify.
Browse topics
What it is
The website widget is a small <script> tag you paste into your own pages. It draws a chat bubble in the corner, and visitors who open it talk to the same chatbot you train in the dashboard.
The whole thing is one tag. There is no npm package to install, no build step, and no server-side integration. The script carries two pieces of information: which chatbot to load (a widget token) and where the Agentency API lives. Everything else — colours, avatar, welcome message, launcher position — is fetched from your chatbot at runtime, which is why changing them in the dashboard never means re-pasting the snippet.
Four things must all be true before the bubble appears on a live site:
- Your plan includes integrations (not Free).
- The chatbot is active.
- The snippet is on the published page, with its attributes intact.
- The page's host is on the chatbot's allowed domains list.
Miss any one of them and you get nothing. Those four are the checklist below, in order.
When you would use it
You control a website and you want the chat available there, rather than sending people to a separate link. If you cannot add a <script> tag — some locked-down site builders will not let you — use the iframe embed or the hosted link instead. See Iframe embed and direct link.
Where to find it
Open Dashboard → Chatbots → your chatbot → Integrations → Web widget.
That is the only place the widget token is shown. It is not on the chatbot list, not on the Playground, and not in any export.
Prerequisites checklist
Before you copy anything, confirm all of these. Working through them now takes two minutes; debugging them afterwards takes an afternoon.
- Your plan includes integrations. Free cannot use the widget at all — the Web widget tab shows an upgrade wall instead of the snippet. See Integrations and plans.
- The chatbot is active. Check the badge on the Playground tab. A draft or paused chatbot refuses the widget. See Activate or pause a chatbot.
- The chatbot has trained knowledge. Not strictly required — the bubble will appear either way — but visitors will be told it is not ready. See Untrained mode.
- You can edit your site's HTML, specifically the
<head>or the end of<body>, on the published template rather than a draft preview. - You know the exact hostnames visitors use, including whether they arrive with or without
www.
The snippet
The Web widget tab generates the snippet for you with your real values already filled in — always copy from there rather than typing this by hand. This is what it looks like, so you know what you are pasting:
<script
src="https://your-agentency-site.com/js/chatbot-widget.js"
defer
data-widget-token="YOUR_WIDGET_TOKEN"
data-api-base-url="https://api.your-agentency-domain.com"
referrerpolicy="strict-origin-when-cross-origin"
crossorigin="anonymous">
</script>
YOUR_WIDGET_TOKEN is the only part that identifies your chatbot, and the dashboard fills it in for you. The rest of the attributes are not decoration:
| Attribute | Why it is there |
|---|---|
defer | The script waits for your page to parse, so the widget never blocks rendering |
data-widget-token | Which chatbot to load. The widget refuses to boot without it |
data-api-base-url | Where the API lives |
referrerpolicy | Limits what address information is sent to third parties |
crossorigin | Required for the script to load correctly cross-origin |
Do not remove any of them, and do not reformat the tag into something your CMS will mangle.
You paste it once
The script address never changes. Widget fixes and new features reach your site on their own within about five minutes, and changes you make to the chatbot's settings apply automatically too — there is never a reason to copy the snippet again. If a snippet you pasted earlier points at a file named chatbot-widget.<letters-and-digits>.js, that older form was pinned to one version and does not update: replace it with the snippet from the dashboard once, and you are done for good.
Never put the token in the URL
An older style passed the token as a query parameter on the script URL. That is deprecated and the loader ignores it. It is also worse for you: a URL ends up in referrer headers, proxy logs, and analytics, while an attribute does not. Keep the token in data-widget-token.
Do not self-host the script
Copying chatbot-widget.js onto your own server is unsupported. You lose automatic updates, and you will spend a long time debugging a widget that behaves like a version from six months ago. Load it from the address the dashboard gives you.
Steps
- Open Dashboard → Chatbots and select the chatbot.
- Confirm on Playground that it is Active.
- Open Integrations and choose the Web widget tab.
- Open the Website embed option and copy the snippet. Optionally adjust the launcher's corner, size, offsets, and auto-open in the configurator first — those choices are written into the snippet as extra attributes, and only non-default values are added. See Change the widget look and position.
- Paste the snippet into your site, just before the closing
</head>tag, on every page that should show the bubble. Before</body>also works. - Publish the change. A snippet sitting in an unpublished draft is the single most common cause of "I pasted it and nothing happened".
- Back on the Web widget tab, find Allowed domains and add your site's hostname — one per line, bare hostnames only. Add both
example.comandwww.example.comif visitors can reach you either way. Save. See Allow the widget on your domains. - Verify (next section).
Verify it actually works
Do not skip this. Checking from the browser tab you have been editing in proves almost nothing.
- Open your live site in a private/incognito window, on the exact address a real visitor uses.
- Confirm the bubble appears in the corner.
- Open it and check the greeting is your welcome message, not a placeholder.
- Send a real question and confirm you get a real answer.
- Repeat on a phone, in portrait. The bubble must not cover a Buy button, a cookie banner, or your navigation.
- Go back to the dashboard, open the chatbot's Conversations tab, and confirm your test appears with the channel shown as Website widget.
That last step is the real proof. If the conversation is there, every one of the four gates passed.
Other embed options on the same tab
The Web widget tab offers more than the standard bubble:
- Your own button — hides the default launcher and lets any element on your page open the chat, so you can use your own styled button or menu item. A button can also send a question as it opens (
data-agentency-message="…"), and the drawer shows the few lines of code a custom button most often needs. - Inline container — mounts the chat inside an element on your page instead of floating over it. Good for a dedicated support section.
- JavaScript API & events — drives the chat from your own code:
open(),close(),toggle(),sendMessage(text),resetConversation(),identify(), anddestroyAll(), plus events such ascloseandmessage:sentthat your page can listen for. The last method matters in single-page apps, where you should tear instances down on route changes to avoid duplicates. See Control the widget from your code. - Iframe — embeds the hosted page instead of the script widget. See Iframe embed and direct link.
- Identify your users — names the person chatting so conversations show "Sara Ali" instead of anonymous. See Name visitors on the widget.
For WordPress, Shopify, Wix, Squarespace, Webflow, and others, there are platform-specific snippets that tell you exactly which settings screen to paste into. See Plugins overview and WordPress plugin.
What you will see
The Web widget tab shows Widget usage at the top — requests today (resetting at midnight UTC), total messages all-time, and the platform rate limits per minute and per day. Below that are the embed option cards, each opening a drawer with its snippet, and the Allowed domains box.
Free workspaces see the same cards, locked, plus the public Direct link — deliberately, so you can see exactly what an upgrade unlocks.
Limits and plan notes
The widget requires a paid plan with integrations (Starter and above). Free is share-link only.
Allowed domains accepts up to 50 entries per chatbot. In production an empty list blocks the widget everywhere — an empty list means "not configured", not "allow everyone".
Widget requests are rate-limited per minute and per day; the current limits are shown on the Web widget tab. Visitors beyond the limit are asked to retry shortly.
Every visitor turn spends message credits at the chatbot's live model rate (1X = one credit). See Message credits.
Common problems
The bubble never appears after I paste the script.
Work the four gates in order: plan, active, snippet present with attributes intact, host on the allowlist. The widget is not showing is the full checklist.
It worked locally and broke when I shipped.
Almost always allowed domains — you had localhost listed and never added the production host. Add it and save.
The Web widget tab says I need to upgrade.
You are on Free. Share the hosted /agent/{handle} link from Integrations → Messaging → Direct link in the meantime — that works on every plan.
The tab says the widget token is unavailable.
The chatbot has no token yet, so no snippet can be generated. Reload; if it persists, contact support.
Two chat bubbles appear on the same page.
The snippet is on the page twice — often once in the theme header and once in a page-level block. Remove one. In a single-page app, call AgentencyWidget.destroyAll() when leaving the route that had the chat, and init() it again when you come back. See Control the widget from your code.
The bubble covers my checkout button on mobile.
Change the corner or increase the offset in the configurator, then recopy the snippet. See Change the widget look and position.
I changed the chatbot's colours and the widget still looks old.
The widget caches its configuration briefly. Hard-refresh, wait a minute, and confirm you are not serving your own copy of the script.
Common questions
Where do I find the widget token?
Only on Dashboard → Chatbots → your chatbot → Integrations → Web widget. It is not on the chatbot list, not on the Playground, and not in any export.
Can I put the token in the script URL instead of an attribute?
No. The loader boots from the data attribute and ignores a token in the URL. An attribute also keeps the token out of referrer headers, proxy logs, and analytics.
Can I host the widget script on my own server?
It is unsupported. You lose automatic updates and end up debugging a version from months ago. Load it from the address the dashboard gives you.
Why are there two chat bubbles on my page?
The snippet is on the page twice, usually once in the theme header and once in a page-level block. Remove one, and in a single-page app call AgentencyWidget.destroyAll() when leaving the route that had the chat.
How do I know it really worked?
Open your live site in a private window, send a real question, then check the chatbot's Conversations tab for a thread with the channel recorded as Website widget.
Do chats from the widget create customer records automatically?
No. A visitor who chats anonymously produces a conversation but no contact. Turn on lead capture for that chatbot, or pass your own visitor identity, before anyone appears under Customers.
Was this article helpful?
Related articles
Allow the widget on your domains
Only listed hostnames may load your widget. An empty list means "not configured", so live sites are blocked.
The widget is not showing
Five gates in order — plan, activation, the snippet, allowed domains, the browser — before you touch your theme.
Change the widget look and position
The launcher lives on Integrations → Web widget; the chat window's avatar and colours live on chatbot Settings.
Hosted page vs website widget
Same knowledge, same credits, same conversations — different identification, different access control, different plans.
Ready to try it on your own content?
Create a free workspace, add a document, and ask the questions your team is tired of answering.