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.