Widget Script Reference

Every script attribute, iframe parameter, and query-string override for the embed widget.

Script embed

HTML
<script
  src="https://your-mozo-domain.com/embed/widget.js"
  data-agent-id="YOUR_AGENT_ID"
  data-position="right"
  async
></script>

The script is served from /embed/widget.js. On load, it injects a fixed-position <iframe> pointing at /widget/{agentId} into document.body. The iframe resizes dynamically based on widget state and the host page viewport width.

Script attributes

AttributeRequiredDescription
data-agent-idYes, unless data-embed-url is setThe agent to load
data-embed-urlNoFull iframe URL override, replacing the default /widget/{agentId} URL
data-positionNo"left" or "right" (default "right") — which corner the widget docks to

Dynamic iframe sizing

StateMobile (≤768px)Desktop (>768px)
Closed80×80px bubble in corner80×80px bubble in corner
OpenFull viewport (100vw × 100dvh)384×600px panel in corner

When the chat is open on mobile, the host page scroll is locked until the user closes the widget. The iframe uses z-index: 2147483647 so it stays above your page's other content. It's sandboxed with allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-same-origin.

Use the script embed (not a manual iframe) for full-screen mobile behavior. A direct iframe embed fills its own container only and cannot overlay the host page.

Iframe embed

If you'd rather control placement yourself instead of a floating widget, embed the iframe directly:

HTML
<iframe
  src="https://your-mozo-domain.com/widget/YOUR_AGENT_ID?embed=floating"
  style="width:360px;height:600px;border:none;"
></iframe>

On viewports ≤768px wide, the widget UI expands to fill the iframe container. For full-screen overlay on mobile (covering the host page), use the script embed above.

PostMessage protocol

The embed script and widget iframe communicate via bidirectional postMessage. This is handled automatically by /embed/widget.js and does not require custom integration.

Iframe to host (mozo-widget-resize)

Sent when the user opens or closes the chat:

JSON
{
  "type": "mozo-widget-resize",
  "state": "open"
}
FieldTypeDescription
type"mozo-widget-resize"Message identifier
state"open" | "closed"Current widget open state

The embed script validates event.source === iframe.contentWindow before applying layout changes. Mobile vs desktop sizing is determined by the host page viewport width, not the iframe.

Host to iframe (mozo-host-viewport)

Sent on iframe load and when the host window is resized:

JSON
{
  "type": "mozo-host-viewport",
  "isMobile": false
}
FieldTypeDescription
type"mozo-host-viewport"Message identifier
isMobilebooleanWhether the host viewport is ≤768px wide

The widget uses this to choose its internal layout (full-screen vs panel) without reading the iframe's own dimensions, which shrink to 80×80px when the bubble is closed.

Query parameter overrides

Both the default widget iframe and a manually embedded iframe accept query parameters that override the agent's saved widget configuration for that specific embed:

ParameterDescription
primaryPrimary color (hex, URL-encoded, e.g. %236366F1)
accentAccent color
backgroundBackground color
textText color
brandBrand name override
logoLogo URL override
profilePictureProfile picture URL override
welcomeWelcome message override
alignmentChat bubble alignment: left or right
embedSet to floating for the floating widget layout

Example:

Code
https://your-mozo-domain.com/widget/YOUR_AGENT_ID?primary=%236366F1&alignment=right&embed=floating

Anything not overridden by a query parameter falls back to the agent's saved configuration from the Embed Widget settings page.

Security

Widget and hosted-page chat requests are authenticated with a short-lived signed session token (header x-widget-session) and checked against the agent's origin allowlist. See Security & Access Control for how to configure allowed origins, since embeds on domains not in the allowlist will be blocked.