Skip to main content
A web widget runs on your site through a single <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>:
<script src="https://your-host/public/embed/{widgetId}" async></script>
Replace {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:
  1. Checks the widget’s allowed-domain list. If the list is non-empty and the current window.location.origin is not on it, the loader logs an error and stops without rendering anything. See Allowed domains and security.
  2. Creates an <iframe> with id anyreach-iframe pointing at /public/widgets/{widgetId}. The real embedding origin is passed as a parentOrigin query parameter so the widget knows where it is hosted.
  3. 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 maximum z-index so it sits above page content.
  4. Exchanges messages with the widget over postMessage to resize and reposition.
┌─────────────────────────────────────┐
│  Your page                          │
│                                     │
│                                     │
│                          ┌────────┐ │
│                          │ iframe │ │  ← fixed, bottom-right
│                          │  chat  │ │     /public/widgets/{id}
│                          └────────┘ │
└─────────────────────────────────────┘

Desktop vs mobile

The loader listens for resize messages from the widget and sizes the iframe to match.
ModeBehavior
DesktopFloating panel anchored to right: 0; bottom: 0, sized to the widget’s reported width and height
MobileFull-screen — the iframe is pinned to all four edges (top, left, right, bottom set to 0)
The widget signals mobile full-screen mode by setting 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 these allow permissions so the widget can run voice and other interactive features:
microphone; camera; display-capture; autoplay; clipboard-write
It also sets loading = 'lazy' and referrerPolicy = 'origin-when-cross-origin'.
The loader only honors postMessage events whose origin matches the Anyreach host and whose payload carries source: 'anyreach-widget'. The parentOrigin value is always derived from the real embedding origin, not from forwarded query parameters, so it cannot be spoofed by the embedding page.

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.
PlatformWhere to add it
WordPressAppearance → Widgets (or Code Snippets) → Footer; paste and save
ShopifyOnline Store → Themes → Edit code → theme.liquid (before </body>); paste
WebflowProject Settings → Custom Code → Footer Code; paste and publish
WixSettings → Custom Code → Add Code to All Pages (body end); paste and publish
SquarespaceSettings → Advanced → Code Injection → Footer; paste and save
Next.jsAdd a next/script snippet in app/layout.tsx with strategy="afterInteractive"
ReactAdd to public/index.html before </body>
VueAdd to public/index.html before </body>
AngularAdd to src/index.html before </body>
For most platforms the generated code is the standard <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:
// app/layout.tsx
import Script from 'next/script'

<Script src="https://your-host/public/embed/{widgetId}" strategy="afterInteractive" />
afterInteractive loads the snippet after the page becomes interactive, which is the right time for a non-blocking chat widget.
React, Vue, and Angular all use the same plain <script> tag — just place it in that framework’s static HTML entry file. The Deploy tab generates the identical snippet for each.

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.