Guides
Iframe embedding
Configure your launch URL, embedding headers, and local development environment.
Allow the Zetapad parent
Send an HTTP CSP header that allows both production parent origins:
Content-Security-Policy: frame-ancestors https://zetapad.com https://www.zetapad.com;
Merge frame-ancestors into any existing CSP rather than replacing unrelated directives. Apply it to every app HTML response, including error pages and nested routes. The directive must be sent in an HTTP header; a meta tag cannot enforce frame-ancestors.
Do not send X-Frame-Options: DENY or SAMEORIGIN on those responses. Both prevent the intended cross-origin embedding. If your host sets either header automatically, override it for your app documents.
frame-ancestors controls which pages may embed your app. It does not block top-level navigation or authenticate callers. Follow restrict app access when the direct URL must be unusable.
Iframe capabilities
The iframe permits scripts, forms, and its own origin. Zetapad does not delegate top navigation, popups, camera, or microphone.
Register the final launch origin. An iframe redirected to another origin cannot use the bridge. Keep navigation within the registered origin, send ready when the app loads, and reopen the Zetapad room after iframe navigation.
Rooms and previews fill the browser viewport. Your app controls its interface. A small transparent Zetapad logo bubble sits above it; members can drag it to an edge and open controls to reload or exit. Consent dialogs appear above the room when needed.
Validate messages
Install your message listener before sending ready. Accept only replies from window.parent with either https://zetapad.com or https://www.zetapad.com as their exact origin. After a valid readiness reply, pin all further messages to that responding origin.
Use an exact origin as the postMessage target. The browser example supports both production origins without using a wildcard target.
Hosted call tiles
Apps using campus calls embed Zetapad-hosted video tiles inside their registered app iframe. Merge a frame-src directive into your app's CSP:
Content-Security-Policy: frame-ancestors https://zetapad.com https://www.zetapad.com; frame-src https://zetapad.com https://www.zetapad.com;
Resolve each relative tile URL against the exact origin pinned by ready, including any local port. Tile and campus origins must match even though production REST requests use https://zetapad.com. Mount tile iframes directly inside the registered app document. Ordinary child iframes work; an extra sandbox must preserve scripts and allow-same-origin so the owning campus can attach its existing video.
Keep the tile on its campus origin, use each returned URL once, and request fresh URLs after reload. Tile documents permit only the registered app and their own campus origin as ancestors. They capture no devices and render muted video; Zetapad retains incoming audio and native camera/microphone controls. See the hosted call example for mounting, commit, heartbeat, and release.
Local development
Unpublished previews may use HTTP on localhost, 127.0.0.1, or [::1], on an origin separate from Zetapad. Publishing always requires HTTPS.
When running Zetapad locally at http://localhost:3000, configure the app document's header as:
Content-Security-Policy: frame-ancestors http://localhost:3000;
Replace the browser example's trusted origins with ["http://localhost:3000"] and the server example's API origin with http://localhost:3000. These changes are for local integration testing. Production uses the fixed Zetapad origins above.
For local hosted tiles, also allow http://localhost:3000 in frame-src and in the call example's tile-origin allowlist. Set its REST helper base URL to http://localhost:3000/v1/apps/calls. Keep the registered app on a different origin or port.
An HTTPS tunnel can help if your browser restricts an HTTP local iframe inside an HTTPS parent.
App session cookies
Zetapad authentication itself does not require third-party cookies. Your own app's session storage still needs to work in an embedded browser context.
Use HttpOnly, Secure cookies on HTTPS. Cross-site iframe cookies generally need SameSite=None; browser privacy settings may still restrict them. Configure a supported session strategy for your app and test it in the intended browsers. The server must resolve the visitor session itself, never accept a session identity from the request body.