Embed the editor
Use @coframe/editor-embed to drop the full Coframe Agent UI into your own
app as an iframe. Your app stays in control: send commands (navigate, send a
message, toggle read-only) and receive typed events back over a cross-origin
postMessage channel — no WebSocket plumbing on your side.
Installation
Section titled “Installation”pnpm add @coframe/editor-embedQuick start (React) — recommended
Section titled “Quick start (React) — recommended”The <EditorEmbed> component wires up the iframe and the message channel for
you:
import { EditorEmbed } from "@coframe/editor-embed/react";
function App() { return ( <EditorEmbed editorBaseUrl="https://editor.example.com" sessionId="my-session" token="capability-token" surface="editor" style={{ width: "100%", height: 600 }} onEvent={(event) => { if (event.type === "ready") console.log("Editor ready"); if (event.type === "annotation-submitted") { console.log("Annotation:", event.submission); } }} /> );}Need to send commands? useEditorEmbed returns an imperative handle:
import { useEditorEmbed } from "@coframe/editor-embed/react";
const embed = useEditorEmbed({ editorBaseUrl: "https://editor.example.com", sessionId: "my-session", token: "capability-token", surface: "editor",});
embed.navigate("https://example.com/pricing");embed.sendMessage("Tighten up the copy here");embed.setReadonly(true);Quick start (vanilla JS)
Section titled “Quick start (vanilla JS)”import { EmbedController } from "@coframe/editor-embed";
const controller = new EmbedController({ editorBaseUrl: "https://editor.example.com", sessionId: "my-session", token: "capability-token", surface: "editor",});
const iframe = document.createElement("iframe");iframe.src = controller.buildIframeSrc();document.body.appendChild(iframe);controller.attach(iframe);
const unsubscribe = controller.onEvent((event) => { if (event.type === "ready") console.log("Editor ready"); if (event.type === "annotation-submitted") { console.log("Annotation:", event.submission); }});
// Drive the editorcontroller.navigate("https://example.com");
// Laterunsubscribe();controller.dispose();Surfaces
Section titled “Surfaces”The surface option selects which view the iframe renders:
| Surface | Shows |
|---|---|
editor (default) | The full editor UI — chat, preview, and panels. |
browser | Just the live in-session browser. |
annotated-browser | The live browser with the annotation overlay. See Collect visual annotations. |
Protocol: coframe:embed/v1
Section titled “Protocol: coframe:embed/v1”Every message carries a protocol: "coframe:embed/v1" field so you can filter
out unrelated postMessage traffic.
Your app → iframe (commands)
Section titled “Your app → iframe (commands)”| Command | Sent via | Description |
|---|---|---|
navigate | controller.navigate(url) | Navigate the live browser to a URL. |
message | controller.sendMessage(text) | Send a chat message to the agent. |
set-panel | controller.setPanel(panel) | Switch the active editor panel. |
set-readonly | controller.setReadonly(bool) | Toggle read-only mode. |
dispose | controller.dispose() | Tear down the embed. |
iframe → your app (events)
Section titled “iframe → your app (events)”onEvent delivers a typed ChildEvent:
event.type | Payload | Description |
|---|---|---|
ready | sessionId, surface | Handshake accepted; editor is ready. |
auth-error | message | The capability token was rejected. |
session-state | isRunning, isAwaitingApproval, lastSeq | Live run state. |
browser-status | status (starting/ready/expired/error) | Live browser lifecycle. |
navigated | url | The browser navigated to a new page. |
annotation-submitted | submission | A user submitted an annotation. |
error | message | An error occurred. |
If you wire up window.addEventListener("message", …) yourself, filter
events with isChildEvent:
import { isChildEvent } from "@coframe/editor-embed";
window.addEventListener("message", (event) => { if (!isChildEvent(event.data)) return; // event.data.type is a known editor event});<EditorEmbed> props
Section titled “<EditorEmbed> props”| Prop | Type | Description |
|---|---|---|
editorBaseUrl | string | Editor-web deployment URL. |
sessionId | string | Session to connect to. |
token | string | Capability token for the auth handshake. |
surface | EmbedSurface | "editor" (default), "browser", or "annotated-browser". |
onEvent | (event: ChildEvent) => void | Receives typed events from the iframe. |
style | CSSProperties | Inline styles for the iframe. |
className | string | Class applied to the iframe. |
title | string | Accessible iframe title (default "Editor"). |
Live demo
Section titled “Live demo”Embed the real Coframe Agent in an iframe and interact via postMessage: