@@ -428,7 +428,13 @@ window.addEventListener('message', function(e) {
428428 content.setAttribute('data-exec-' + hash, '1');
429429 try {
430430 var newScript = document.createElement('script');
431- if (scriptInfo.type) newScript.type = scriptInfo.type;
431+ // Auto-detect ES module syntax: if the script contains import/export
432+ // statements but lacks type="module", promote it so the import map applies.
433+ var effectiveType = scriptInfo.type;
434+ if (!effectiveType && scriptInfo.text && /\\b(import\\s|export\\s|import\\()/.test(scriptInfo.text)) {
435+ effectiveType = 'module';
436+ }
437+ if (effectiveType) newScript.type = effectiveType;
432438 if (scriptInfo.src) {
433439 newScript.src = scriptInfo.src;
434440 newScript.onload = function() { runScripts(scripts, idx + 1); };
@@ -471,6 +477,20 @@ function assembleShell(initialHtml: string = ""): string {
471477<head>
472478 <meta charset="utf-8">
473479 <meta name="viewport" content="width=device-width, initial-scale=1">
480+ <script type="importmap">
481+ {
482+ "imports": {
483+ "three": "https://esm.sh/three",
484+ "three/": "https://esm.sh/three/",
485+ "gsap": "https://esm.sh/gsap",
486+ "gsap/": "https://esm.sh/gsap/",
487+ "d3": "https://esm.sh/d3",
488+ "d3/": "https://esm.sh/d3/",
489+ "chart.js": "https://esm.sh/chart.js",
490+ "chart.js/": "https://esm.sh/chart.js/"
491+ }
492+ }
493+ </script>
474494 <meta http-equiv="Content-Security-Policy" content="
475495 default-src 'self';
476496 script-src 'unsafe-inline' 'unsafe-eval'
@@ -590,8 +610,8 @@ export function WidgetRenderer({ title, description, html }: WidgetRendererProps
590610
591611 const iframe = iframeRef . current ;
592612 if ( iframe . contentWindow ) {
593- // targetOrigin "*" is required: the sandboxed iframe (allow-scripts only,
594- // no allow-same-origin) has a null origin , so no specific origin can be used.
613+ // targetOrigin "*" is required: sandboxed iframes may have a null origin
614+ // depending on browser , so no specific origin can be used.
595615 iframe . contentWindow . postMessage (
596616 { type : "update-content" , html } ,
597617 "*"
@@ -680,7 +700,10 @@ export function WidgetRenderer({ title, description, html }: WidgetRendererProps
680700 content streamed via postMessage for progressive rendering. */ }
681701 < iframe
682702 ref = { iframeRef }
683- sandbox = "allow-scripts"
703+ // allow-same-origin is required for import maps to work in srcdoc iframes.
704+ // Safe here because no auth/session data is exposed client-side.
705+ // See: https://github.com/CopilotKit/OpenGenerativeUI/issues/3
706+ sandbox = "allow-scripts allow-same-origin"
684707 className = "w-full border-0"
685708 onLoad = { ( ) => setLoaded ( true ) }
686709 style = { {
0 commit comments