Appearance
iframe (no JavaScript)
Where you can't add scripts (some site builders, a help-centre template, an internal page), embed the chat window itself:
html
<iframe
id="chat"
src="https://chat.example.com/embed/pk_your_bot_id"
title="Chat with us"
allow="microphone; camera; autoplay; clipboard-write"
style="width: 100%; max-width: 420px; height: 640px; border: 0; border-radius: 16px"
></iframe>allow lets the chat use the microphone and camera (for voice and the webcam) and play sound. Leave it out if the bot uses neither.
How it differs from the script tag
The /embed/ page is the chat window running on its own:
- It is always open, and you size it with the iframe. There's no launcher, greeting bubble or unread count.
- There's no widget.js on your page, so no page tools, and no JavaScript API. A smaller set of commands and events works over
postMessage(below). - The chat remembers the visitor in the chat server's own storage inside the iframe. Browsers that partition or block third-party storage (Safari, and others in private modes) may forget the conversation on reload.
- The bot's allowed origins still apply. The iframe can only be shown on those sites, and the chat checks which page it is on from the referrer: keep the browser's default referrer policy (don't add
referrerpolicy="no-referrer").
Everything else (text, voice, images, the camera, hand-off, leads) works as usual.
Talking to it from your page
Your page can send the iframe commands with postMessage, and hear its events. Messages are objects with wireface: 1, a type t and data d. The chat only accepts them from its parent window, at the origin that embeds it, and only sends its events there. Messages over 64 KB are ignored.
js
const chat = document.querySelector('iframe#chat').contentWindow;
const CHAT_ORIGIN = 'https://chat.example.com';
// send a message as the visitor
chat.postMessage({ wireface: 1, t: 'send', d: { text: 'Where is my order?' } }, CHAT_ORIGIN);
// hear what happens
window.addEventListener('message', e => {
if (e.origin !== CHAT_ORIGIN || e.data?.wireface !== 1) return;
if (e.data.t === 'event') console.log(e.data.d.name, e.data.d.data); // e.g. "message", { role, text, ... }
if (e.data.t === 'error') console.warn(e.data.d.code, e.data.d.message);
});Command t | d |
|---|---|
send | { text }: send a message as the visitor |
prefill | { text }: put text in the message box |
identify | { userId, userHash, name, email, traits }: see Identity verification (note the field names) |
context | { context, merge }: facts for the agent; merge: true adds to earlier ones |
update | { theme, accentColor, locale, strings } (a new locale is passed on to the agent) |
page | { url, title }: the page changed |
conversation.new | {} |
voice.start, voice.stop | { mode, camera } (mode: conversation or ptt; camera: true also offers the camera), {} |
The chat posts back ready (d: { conversationId, visitorId, ... }, when it connects), event (d: { name, data }, with the same names and data as the widget's events, such as message, conversation, handoff and lead) and error (d: { code, message, recoverable }).
Linking to the chat as a page
https://chat.example.com/embed/pk_your_bot_id also works as a page of its own, for a link in an email or an app. Opened directly, it isn't on any of your sites, so add the chat server's own address (https://chat.example.com) to the bot's allowed origins.