Skip to main content
← All docs
UUsable
    usable/chat assistants

    Integrate embedded Chat

    Bergur Davidsen·Updated 2026-07-14

    |Open in||History

    A Chat embed runs the Usable assistant UI inside a parent application. The generated iframe or SDK snippet handles the basic startup contract; the parent bridge can add runtime context, parent-local tools, theme and fullscreen behavior, link handling, and parent-owned persistence.

    Start from the snippet copied from Configure an embedded assistant. It reflects the current released protocol and configuration identifiers. Avoid rebuilding the startup URL from memory.

    Choose iframe or SDK startup

    Use the generated iframe when the host needs a straightforward embedded surface and can implement the documented postMessage bridge.

    Use the generated SDK integration when you want a wrapper for mounting, startup, and supported bridge operations. Pin and review the SDK according to your application's dependency policy; do not assume an old copied example matches the current release.

    In both cases:

    • serve the host over HTTPS in production;
    • use the exact allowed host origin;
    • give the iframe a stable container;
    • allow only the frame and network origins required by your content security policy;
    • keep secrets and long-lived credentials out of client source.

    Wait for READY

    Do not send initialization-dependent messages as soon as the iframe element is created. Wait until the child sends the released READY signal, then register or send runtime state.

    Queue early host updates and flush them after readiness. Also handle a child reload: it can become ready again and need current context, theme, or tools re-sent.

    A robust parent treats readiness as a handshake, not a fixed timeout.

    Validate every bridge message

    For every inbound message event, validate both:

    • event.origin exactly equals the expected Usable Chat origin;
    • event.source exactly equals the mounted iframe's contentWindow.

    Reject unknown message types and malformed payloads. When replying, use the exact child origin as targetOrigin, never *.

    Example shape:

    window.addEventListener("message", (event) => {
      if (event.origin !== expectedChatOrigin) return;
      if (event.source !== iframe.contentWindow) return;
      if (!isSupportedChatMessage(event.data)) return;
      handleChatMessage(event.data);
    });

    Origin checks prevent other pages from impersonating Chat. Source checks prevent another frame on the same origin from entering this integration.

    Bearer acquisition and refresh

    The embed uses its configuration and released credential flow to acquire an authorized bearer. Handle the bridge's bearer request and refresh behavior exactly as shown by the generated integration.

    The parent should:

    • obtain short-lived credentials from an authenticated backend where required;
    • bind authorization to the current user and configuration;
    • refresh before or after expiry according to the protocol;
    • fail visibly when refresh cannot be completed;
    • clear state when the user signs out.

    Never expose an unrestricted personal access token, service secret, or permanent bearer in browser code.

    Send runtime context

    After readiness, the parent can send context relevant to the current page, record, or user. Send stable identifiers and minimal descriptive data rather than the entire application state.

    Runtime context can augment or replace configured defaults according to the released configuration. It cannot grant access to a workspace or source the credential cannot read.

    When the host route changes, update context deliberately and indicate whether old context should remain. Do not leave one customer's record active when the user navigates to another.

    Register parent tools

    Parent tools let the assistant request actions owned by the host application. Register their names, descriptions, and input schemas after readiness.

    For each call:

    1. Validate the bridge origin, source, tool name, and arguments.
    2. Authenticate and authorize the current user on the server.
    3. Execute the smallest approved action.
    4. Return JSON-safe data or a structured error.
    5. Enforce timeouts and idempotency where retries are possible.
    6. Log security-relevant actions without logging secrets.

    The assistant's tool choice is untrusted input. Never rely on the model or iframe to decide whether a user may read, update, send, purchase, or delete something.

    Parent tools can include Skill metadata to improve discovery. Metadata describes use; host authorization remains mandatory.

    Native UI, fullscreen, links, and theme

    The child can request host-owned UI behavior where enabled, including native dialogs, fullscreen changes, external link opening, or theme synchronization.

    The parent decides whether to honor each request. Validate URLs before opening them, preserve an accessible way to exit fullscreen, and avoid allowing the child to navigate the top-level page arbitrarily.

    If native UI is disabled, provide an explicit fallback or error instead of silently dropping a request.

    Attachments and workspace files

    Uploads, workspace files, and host-provided file tools are separate capabilities. Gate them in configuration and enforce file rules in the host or backend.

    Validate size, type, ownership, scanning status, and retention. Do not treat a file handle from a bridge message as proof that the current user owns the file.

    Parent-owned persistence

    For stateless embeds, persist conversation state in the authenticated parent backend. Preserve message order, branch identity, tool results, and the context version needed to reconstruct the experience.

    Do not trust a client-supplied conversation owner. Enforce tenancy and user access on every load and save.

    Production troubleshooting

    The iframe never becomes ready

    Check the Chat URL, frame CSP and frame-src, configuration state, allowed origin, browser console, and network failures. Confirm you are listening before the child emits readiness.

    Messages work locally but not in production

    Compare exact origins, including scheme and port. Remove wildcard targetOrigin workarounds and update the configuration allowlist.

    Authentication loops

    Check configuration expiry, backend session state, clock skew, refresh handling, and sign-out cleanup. Do not solve the loop by issuing a non-expiring browser credential.

    Context is stale after navigation

    Send a route-aware runtime-context update after readiness and on relevant host changes. Clear prior record-specific context explicitly.

    A parent tool hangs

    Return a structured timeout, make retries safe, and verify that tool registration occurred after the latest readiness handshake.

    Fullscreen or links behave incorrectly

    Validate the child request and implement host-controlled behavior. Browser popup and iframe policies may require a direct user gesture.

    Related pages

    • Configure an embedded assistant
    • Models, modes, and privacy
    • Experts, tools, and Skills
    • Personal access tokens
    PreviousConfigure an embedded assistantNextConnect an AI client to Usable