Client API & protocol
uframe/embed exposes one function, createUframeEditor, which mounts the iframe and drives it over a small typed postMessage protocol.
createUframeEditor(options)
ts
import { createUframeEditor } from 'uframe/embed'
const editor = createUframeEditor({
target, // HTMLElement: a container (an <iframe> is created inside) or an existing <iframe>
src, // URL of the hosted editor app (index.html)
document, // optional initial PageDocument
readonly, // optional, default false
theme, // 'light' | 'dark'
onReady, // editor mounted and handshaked
onChange, // (document) => void — fired on edits
onSave, // (document) => void — fired on explicit save
onError, // (message) => void
})Options
| Option | Type | Notes |
|---|---|---|
target | HTMLElement | Where to mount. A non-<iframe> element is used as a container (an <iframe> is created inside it); pass an existing <iframe> to drive it directly. |
src | string | URL of the hosted editor app. |
document | PageDocument | Initial page; omitted → starts empty. |
readonly | boolean | Render without editing affordances. |
theme | 'light' | 'dark' | Initial theme. |
plugins | string[] | URLs of plugin dist modules to load + register on ready. |
onReady / onChange / onSave / onError | callbacks | Lifecycle + data out. |
Returned handle
ts
editor.setDocument(doc) // replace the current document
editor.setReadonly(true) // toggle read-only
editor.setTheme('dark') // switch theme
editor.loadPlugins(['/plugins/callout/dist/index.js']) // load + register plugin dists by URL
editor.requestSave() // ask the editor to emit a `save`
editor.destroy() // remove listeners + iframe
editor.iframe // the underlying <iframe> elementProtocol
The handshake: the iframe posts uframe:ready; the client replies with uframe:load (document + options). Every message is namespaced with a uframe: prefix and carries a numeric v (protocol version) field.
| Host → editor | Editor → host |
|---|---|
uframe:load, uframe:setDocument, uframe:setReadonly, uframe:setTheme, uframe:loadPlugins, uframe:requestSave | uframe:ready, uframe:change, uframe:save, uframe:error |
PageDocument is plain JSON, so it travels through postMessage's structured clone unchanged.
Security
- Serve the editor app from an origin you control and pass it as
src. - Both sides validate the message
originandsource; the host origin is passed to the iframe on its URL so replies are targeted, never*. - Allow framing that origin in your host's CSP (
frame-src).