Skip to content

EmbedChat Component ​

Chat for a page shown inside another page (an iframe), signed in with an identity token the host page's server signs. It runs the postMessage handshake, trades the token for an in-memory session, keeps that session alive, reports events to the host page and lets the agent call the host page's tools.

New in 0.4.0

EmbedChat and its helpers are new. The protocol, the events, the origin checks and a complete host page are in Embedding the Chat; this page is the component reference.

A chat inside a host page, with an approval card

Import ​

tsx
import { EmbedChat, type EmbedChatProps, type EmbedClientToolDeclaration, type EmbedSessionApi } from "@cognipeer/chat-ui";
import "@cognipeer/chat-ui/styles.css";

Usage ​

tsx
<EmbedChat
  baseUrl="/api/portal/support"
  allowedOrigins={["https://app.example.com"]}
  clientTools={[{ name: "open_ticket", inputSchema: { type: "object", required: ["id"], properties: { id: { type: "number" } } }, timeoutSeconds: 30 }]}
  eventContent="none"
  showHistory={false}
  theme="dark"
/>

Props ​

EmbedChatProps is ChatProps without transport, authorization, headers, getHeaders, fetch, onClientToolCall, controllerRef and getMessageMetadata (the embed owns them), plus:

PropTypeDefaultDescription
baseUrlstringrequiredThe portal's chat API, for example /api/portal/support
sessionUrlstring<baseUrl>/embed/sessionWhere the host's token is exchanged (POST) and the session revoked (DELETE)
allowedOriginsstring[]requiredOrigins that may embed the page: exact matches, no wildcards
hostOriginstringthe origin query parameterThe embedding page's origin as it declared itself
clientToolsEmbedClientToolDeclaration[][]{ name, description?, inputSchema?, timeoutSeconds? }: the only host-page tools that exist for the agent
eventContent"none" | "text""none"Whether message events carry the message text (4000 characters at most)
wrapChat(chat, session: EmbedSessionApi) => ReactNode-Draw something around the chat once the person is signed in (a terms gate, a banner)
authTimeoutMsnumber10000Wait for the host's first token before the screen says so and auth:required is sent
readyIntervalMsnumber500How often cp:ready is repeated
fetch, windowglobalsFor tests and special setups

EmbedSessionApi is { getHeaders(): Record<string, string>; fetch: typeof fetch; user?: { name?; email? } }: the headers (a bearer token) and a fetch that renews the session once after a 401, for requests made by the pieces you draw around the chat (for example the terms acceptance).

EmbedChat also forwards your own onMessageSent, onMessageReceived, onConversationCreated, onActionRequired, onActionResolved, onBudgetReached and onError after reporting the matching event to the host.

What it renders ​

Until the first session exists it renders a status screen instead of the chat: connecting, waiting for the host, signing in, refused (origin or framing), sign-in failed, session expired or signed out. All strings are in the chat.embed.* group.

Building your own bridge ​

The pieces EmbedChat is made of are exported for hosts that need something different:

ExportPurpose
EmbedBridgeThe iframe's end of the conversation with the host: start() (returns a refusal reason, or starts), stop(), requestToken(reason), emit(event, data), callTool(call, timeoutMs). Posts only to window.parent with the declared origin as target, and listens only to the parent window at that origin
isAllowedOrigin(origin, allowed), normalizeOrigin(value)Exact origin matching
parseHostMessage(data)Validates a message from the host (undefined for anything that is not ours)
exchangeToken({ url, token, fetch?, signal? })POST { token } with no cookies; resolves an EmbedSession or rejects with an ExchangeError (code, status?, reference?)
parseExchangeResponse(body, now), renewalLeadMs(session)Reading the answer; how long before its end a session is renewed
EMBED_PROTOCOL_VERSION, EMBED_EVENTS, MAX_TOKEN_CHARS, MAX_CONTEXT_BYTES, MAX_TOOL_OUTPUT_BYTESProtocol constants

BridgeRefusal is "not_framed" | "origin_not_allowed" | "ancestor_mismatch".

Studio · Pulse · Console · Agent SDK and more — the Cognipeer documentation hub