diff --git a/apps/mesh/src/web/components/deck/use-deck-editor.ts b/apps/mesh/src/web/components/deck/use-deck-editor.ts index 53514e693b..4420ad1b58 100644 --- a/apps/mesh/src/web/components/deck/use-deck-editor.ts +++ b/apps/mesh/src/web/components/deck/use-deck-editor.ts @@ -123,6 +123,9 @@ export function useDeckEditor(args: { }; const postToIframe = (msg: DeckHostMessage) => { + // Deck iframes are sandboxed (opaque origin) so we must use "*" here — + // a sandboxed iframe's origin is "null" and no targetOrigin string can + // match it. The iframe's own message listener validates e.source instead. machine.iframe?.contentWindow?.postMessage(msg, "*"); }; diff --git a/apps/mesh/src/web/components/sandbox/preview/preview.tsx b/apps/mesh/src/web/components/sandbox/preview/preview.tsx index 0fb9c2a320..395324f640 100644 --- a/apps/mesh/src/web/components/sandbox/preview/preview.tsx +++ b/apps/mesh/src/web/components/sandbox/preview/preview.tsx @@ -378,19 +378,29 @@ export function PreviewContent() { }; }, [sectionsOpen]); + const getPreviewOrigin = (): string => { + try { + return previewUrl + ? new URL(previewUrl, window.location.href).origin + : window.location.origin; + } catch { + return window.location.origin; + } + }; + const injectVisualEditor = () => { const win = previewIframeRef.current?.contentWindow; if (!win) return; win.postMessage( { type: "visual-editor::activate", script: VISUAL_EDITOR_SCRIPT }, - "*", + getPreviewOrigin(), ); }; const deactivateVisualEditor = () => { const win = previewIframeRef.current?.contentWindow; if (!win) return; - win.postMessage({ type: "visual-editor::deactivate" }, "*"); + win.postMessage({ type: "visual-editor::deactivate" }, getPreviewOrigin()); }; const injectCmsEditor = () => { @@ -398,14 +408,14 @@ export function PreviewContent() { if (!win) return; win.postMessage( { type: "visual-editor::activate", script: CMS_EDITOR_SCRIPT }, - "*", + getPreviewOrigin(), ); }; const deactivateCmsEditor = () => { const win = previewIframeRef.current?.contentWindow; if (!win) return; - win.postMessage({ type: "cms-editor::deactivate" }, "*"); + win.postMessage({ type: "cms-editor::deactivate" }, getPreviewOrigin()); }; const handleViewModeChange = (mode: PreviewViewMode) => { diff --git a/packages/sandbox/shared.ts b/packages/sandbox/shared.ts index f6b17e9007..e477174cc9 100644 --- a/packages/sandbox/shared.ts +++ b/packages/sandbox/shared.ts @@ -50,4 +50,4 @@ export { * Must run before the framework builds its WS — spliced after `` by * `injectBootstrap` in image/daemon/proxy.mjs. */ -export const IFRAME_BOOTSTRAP_SCRIPT = ``; +export const IFRAME_BOOTSTRAP_SCRIPT = ``;