<script> tag. The script loads a small loader from Anyreach that injects the chat widget into the page. You only need to add it once, anywhere before the closing </body> tag.
The snippet
Paste this just before</body>:
{widgetId} with your widget’s ID. You don’t have to build this by hand — the Deploy tab generates the exact snippet for your widget and host. See Creating a widget to get a widget ID.
The async attribute lets the script load without blocking page rendering. The loader appends the widget to document.body (falling back to document.documentElement), so the snippet works regardless of where in the page you place it.
The
src host is the Anyreach domain serving your widget. The Deploy tab fills in the correct host for you, so copy the generated code rather than typing the URL manually.What the loader does
The script at/public/embed/{widgetId} returns JavaScript (served as application/javascript) that runs immediately on load. It:
- Checks the widget’s allowed-domain list. If the list is non-empty and the current
window.location.originis not on it, the loader logs an error and stops without rendering anything. See Allowed domains and security. - Creates an
<iframe>with idanyreach-iframepointing at/public/widgets/{widgetId}. The real embedding origin is passed as aparentOriginquery parameter so the widget knows where it is hosted. - Pins the iframe to the bottom-right of the viewport using
position: fixed, starting at button size (92px x 92px) with a transparent background and the maximumz-indexso it sits above page content. - Exchanges messages with the widget over
postMessageto resize and reposition.
Desktop vs mobile
The loader listens forresize messages from the widget and sizes the iframe to match.
| Mode | Behavior |
|---|---|
| Desktop | Floating panel anchored to right: 0; bottom: 0, sized to the widget’s reported width and height |
| Mobile | Full-screen — the iframe is pinned to all four edges (top, left, right, bottom set to 0) |
mobile: true on its resize message. The loader also sends the host viewport size (window.innerWidth / window.innerHeight) to the widget on load and on every window resize, and responds to request-viewport messages, so the widget can decide which layout to use.
Permissions
The iframe is created with theseallow permissions so the widget can run voice and other interactive features:
loading = 'lazy' and referrerPolicy = 'origin-when-cross-origin'.
Per-platform instructions
The Deploy tab on the widget config screen lists supported platforms. Click a platform to open a dialog with paste-ready instructions and the embed code, then click Copy.| Platform | Where to add it |
|---|---|
| WordPress | Appearance → Widgets (or Code Snippets) → Footer; paste and save |
| Shopify | Online Store → Themes → Edit code → theme.liquid (before </body>); paste |
| Webflow | Project Settings → Custom Code → Footer Code; paste and publish |
| Wix | Settings → Custom Code → Add Code to All Pages (body end); paste and publish |
| Squarespace | Settings → Advanced → Code Injection → Footer; paste and save |
| Next.js | Add a next/script snippet in app/layout.tsx with strategy="afterInteractive" |
| React | Add to public/index.html before </body> |
| Vue | Add to public/index.html before </body> |
| Angular | Add to src/index.html before </body> |
<script> tag shown above. Next.js is the exception.
Next.js
Next.js does not allow a raw<script> tag in the rendered tree the same way, so use the next/script component with the afterInteractive strategy:
afterInteractive loads the snippet after the page becomes interactive, which is the right time for a non-blocking chat widget.
Next steps
Creating a widget
Configure appearance, behavior, and the agent behind the widget.
Allowed domains and security
Restrict which sites can load the widget.

