Skip to content
Channels

Install the chat widget

Paste one script tag into your site's HTML, before the closing body tag, on every page you want the bubble on. The tag carries your widget key, which is public by design — it is the same key the browser would show anybody who reads your page source. Nothing else needs to change, and the agent page's install check will tell you within seconds whether we have seen it load.

Updated 2026-09-19 · 6 min read · More in channels

The tag

The snippet is about six kilobytes gzipped, loads asynchronously, and draws nothing but a floating launcher until somebody shows intent — hover, focus, touch or click. Only then does it create the iframe that holds the conversation. A page nobody chats on pays for one small script and nothing else.

Copy it from Install on the agent, rather than from here: the page fills in your own key. Put it on every page you want the bubble on, not just the home page — a customer with a question is usually deep in your site, on a product or pricing page.

  1. Copy the snippet

    Agents → your agent → Install. The key in it is yours; the URL is the same for everyone.

  2. Paste it before </body>

    In your theme's footer, a global layout file, or a tag manager container that fires on all pages.

  3. Publish, then run the check

    The install check on the same page turns green once a real page load has reported in. It is reading the database, not your word for it.

On the platform you actually use

The install page has step-by-step instructions for Google Tag Manager, WordPress, Shopify, Webflow, Squarespace and React or Next.js, because the honest answer to 'where does this go' is different on each of them. If somebody else edits your website, the same page will email them the snippet and the instructions without you having to paste anything into a message.

Two copies of the script on one page is a common outcome of installing it twice — once in the theme and once in a tag manager — and it is harmless: the second copy notices the first and stands down rather than drawing a second bubble.

Lock it to your domains

A new widget answers from anywhere, which is the right default while you are testing and the wrong one once you are live. Add your domains under the widget's allowed list and two things start enforcing it: the config endpoint refuses an origin nobody listed, and the page itself refuses to render inside a frame on an unlisted site.

A bare domain covers its subdomains, so listing example.com also covers shop.example.com. Add your staging host too, or you will lock yourself out of your own test environment.

Change how it behaves on one page

Most of the look and wording lives under Appearance and applies everywhere. When one page needs to differ, put the difference on the tag: the side it sits on, its colour, its label, its offsets, its z-index, whether it hides on mobile, whether it opens full-screen on mobile, and whether it opens by itself. Each of those beats the saved setting, on that page only.

You can also drive it from your own buttons. Any element marked to open, close or toggle the widget does so with no JavaScript from you at all, and an open action can carry a question to prefill — a 'Ask about shipping' link on a product page opens the bubble with the question already typed.

When visitors are signed in

For a widget on pages behind your own login, you can tell us who the visitor is in a way they cannot forge: your server signs their user id with the widget's identity secret, and the page passes the signature along. A verified visitor's chat is keyed to their email address, which merges it with the threads they started by mail, so your team sees one history instead of three.

It is off unless you set it up, and a widget with no secret behaves exactly as an anonymous widget always has. If the bubble should only ever appear behind your login, you can also require identity outright and have it refuse anonymous visitors.

FAQ

Related questions

Yes — it identifies the widget, it does not authorise anything. It is designed to be readable in your page source. What stops abuse is the allowed-domains list, the per-origin refusal on the config endpoint, and your spend cap.

Still stuck? A person will answer.