Iframe embedding
Embed Casual Sheets in any host via iframe + postMessage. Same protocol as Casual Editor.
Casual Sheets exposes the same iframe protocol as Casual Editor. A host that integrates one product can light up the other by swapping the iframe src and the field anchors. Every envelope’s app field is 'sheet'; every other shape is identical.
This is the right delivery when:
- The host isn’t a React app.
- You need a strong security boundary (CSP, frame-ancestors).
- The editor’s release lifecycle must be independent.
For React hosts embedding into their own tree, see the SDK delivery.
Embed shape
<iframe
src="https://sheets.example.com/embed?app=sheet&config=<base64url-JSON>"
allow="clipboard-write; clipboard-read"
></iframe>
config carries an EmbedConfig:
interface EmbedConfig {
app: 'sheet'; // discriminator — must match the iframe build
hostOrigin: string; // required — allowed postMessage origin
locale?: string;
theme?: 'light' | 'dark' | 'system';
hideTitleBar?: boolean;
hideMenuBar?: boolean;
readOnly?: boolean;
}
Differences from Casual Editor
- Field anchor in signing envelopes — Casual Sheets uses
{ kind: 'sheet', sheet: string, cell: string }instead of{ kind: 'doc', paraId: string }. appdiscriminator — every envelope carriesapp: 'sheet'. Hosts embedding both products route by this field.- Selection events —
casual.selection.changed.data.sheetcarries{ sheet, from, to }instead of{ paraId, from, to, selectedText }.
Every other envelope shape — handshake, load.request / response, save.request / response, telemetry, lock, command.*, signature.* — is byte-identical to the Casual Editor protocol. See the full contract.
Signature anchor
When a host issues casual.signature.request against an embedded sheet:
iframe.contentWindow.postMessage(
{
type: 'casual.signature.request',
app: 'sheet',
id: 'sig-1',
v: 1,
data: {
mode: 'sequential',
fields: [
{
fieldId: 'accountant',
label: 'Accountant signature',
required: true,
anchor: { kind: 'sheet', sheet: 'Q3 P&L', cell: 'B47' },
methods: ['drawn', 'typed'],
},
],
banner: 'Signing as Alice for Acme Co.',
},
},
'https://sheets.example.com',
);
The signing pane walks the signer through; drawn signatures stamp as floating images over the target cell range, typed signatures land in the cell directly. See Signatures.
Security model
- Origin validation. Both sides MUST check
event.originagainst the allowlist. Mismatches silently dropped. - Auth token. Optional
host.hello.data.authToken— the editor echoes it on every authenticated request; the host validates as it would any other bearer. - No editor-side auth. The host owns auth.
- Frame ancestors. Production:
Content-Security-Policy: frame-ancestors <host-origin>.
Reference sequence
Identical to Casual Editor’s — only the app field differs.
Source of truth
The iframe protocol contract lives in the Casual Editor repo — both products implement it in lockstep. When the contract changes, both repos update.