Embed the widget

The Embed profile puts an OCP chat on any page: a loader mounts an IFRAME (origin isolation), the page talks to it over origin-checked postMessage, and only the iframe holds the WSS leg to the Hub.

npm install @schwaizer/ocp-embed

Host page integration

import { EmbedHost } from '@schwaizer/ocp-embed';

const host = new EmbedHost({
  config: { siteKey: 'site_xxx', hub: 'https://hub.example', allowedOrigins: ['https://shop.example'] },
  messaging,          // postMessage to the iframe + window message events
  readDom: () => ({   // zero-config context capture
    url: location.href,
    title: document.title,
    metaDescription: document.querySelector('meta[name=description]')?.getAttribute('content') ?? null,
    selection: getSelection()?.toString() ?? null,
  }),
});
host.start();
host.on((e) => analytics(e));   // ocp.state / ocp.event — content never leaves the iframe
host.setContext();              // full replace; call again when the page changes
host.open();

Messages you send before the iframe reports ready are queued and flushed on ready — the loader core handles that. Both directions of the bridge are pinned to the Hub origin: a spoofed postMessage from any other origin is dropped, and host messages target the exact Hub origin.

Rules that keep T0 safe

  • Site key + origin allowlist (exact origins or *.suffix; * is dev-only).
  • The widget is cookie-less at T0; visitor continuity via localStorage with a rotating id.
  • ocp.identify(visitorJws) upgrades to T1 with a tenant-signed visitor identity — signed by YOUR backend, never minted in the browser.
  • Serve the loader with SRI hashes.