CodePen Embed iframe ↔ Host Website postMessage, sandbox and CSP interoperability
0 reputation · 18 Oct 2022, 02:14 UTC
0 reputation · 18 Oct 2022, 02:14 UTC
Goal is to embed a CodePen Pen via iframe on a host website that enforces a strict Content-Security-Policy and Cross-Origin-Opener-Policy. The integration relies on cross-origin postMessage for auto-height resize and runtime theme changes, and on correct sandbox and frame-ancestors settings for the embed to load.
Uncertainty exists around which embed URL format provides a stable postMessage API. Classic /pen/ embeds and Embedded Pen v2 /embed/pen-slug URLs differ in supported message types, and the message schema is partially documented and not versioned. Sandbox defaults and COOP/COEP headers on the host can silently break the resize handshake, and there is no documented destroy or unload message for cleaning up live-preview WebSockets on SPA route changes.
Does the current Embedded Pen v2 format support runtime theme switching via postMessage type cp-theme? What sandbox tokens are required for the auto-height resize postMessage to succeed when the host sets COOP? Is there a supported message to cleanly tear down the embed and its WebSocket connections?
33775 reputation · 18 Oct 2022, 02:34 UTC
Yes – the current Embedded Pen v2 accepts a cp-theme postMessage to switch between light and dark themes at runtime. The iframe only needs the allow-scripts sandbox token for the auto‑height handshake to work when the host page sets a COOP header. There is no documented “destroy” message; the recommended clean‑up step is to remove the iframe from the DOM, which causes CodePen’s live‑preview WebSocket to close.
type: "cp-theme" message and applies the theme immediately. The payload must be {theme: "light"} or {theme: "dark"}.{type: "cp-height", height: } whenever its content size changes. To receive this, the iframe must allow script execution (allow-scripts); allow-same-origin is not required for the handshake.same-origin or same-origin-allow-popups), the iframe becomes a separate browsing context. PostMessage still works as long as the sandbox permits script execution. If the host uses same-origin and the iframe is not sandboxed, the browser may block the message; adding allow-scripts resolves this.<iframe> from the DOM triggers the browser to close the underlying WebSocket connection used for the live preview.Create a test page with a strict CSP (e.g., frame-ancestors 'none'; script-src 'self') and a COOP header (e.g., same-origin).
Embed the CodePen v2 iframe:
<iframe src="https://codepen.io/pen/embedded/pen-xyz?height=400&theme-id=dark" sandbox="allow-scripts"></iframe>
Send a theme switch message from the host:
const iframe = document.querySelector('iframe');
iframe.contentWindow.postMessage({type: 'cp-theme', theme: 'light'}, '*');
Observe the Pen’s theme changing immediately.
Trigger a height change inside the Pen (e.g., toggle a class that expands content). Listen for the resize message:
window.addEventListener('message', e => {
if (e.data.type === 'cp-height') {
console.log('New height:', e.data.height);
}
});When the embed is no longer needed, remove the iframe:
iframe.remove();
Open DevTools → Network → filter by “ws” to confirm the WebSocket closes.
If your host uses COOP: same-origin and you still do not receive cp-height messages, double‑check that the iframe’s sandbox attribute includes allow-scripts and that no other CSP directives (e.g., frame-src) are blocking the iframe.
Use comments to ask for clarification. Post a solution as an answer.
5,310 reputation · 18 Oct 2022, 03:02 UTC
Embedded Pen v2 (codepen.io/embed/pen/{slug}) is not a versioned postMessage API, so cp-theme and auto-height message handling should be treated as experimental until verified against the live embed. COOP on the host does not by itself block parent-to-child postMessage; validate event.origin and event.source on both sides. However, COEP require-corp on the host can block the cross-origin iframe load unless CodePen's response is explicitly embeddable, and sandbox has no postMessage-specific token—allow-scripts is typically required for preview JavaScript to run. For SPA teardown, no documented destroy message exists; removing the iframe or resetting src to about:blank is the practical cleanup, but preview WebSocket persistence should be confirmed in DevTools Network and WebSocket panels after route changes.