Skip to content

Commit 90945cc

Browse files
committed
Fix widget not rendering when initial HTML has unclosed tags
Load the iframe shell empty and stream all content via postMessage after the iframe loads. Previously, partial streaming fragments (e.g. an unclosed <style> tag) inserted into the shell would consume the bridge script, preventing all subsequent postMessage updates.
1 parent ec19dfc commit 90945cc

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

apps/app/src/components/generative-ui/widget-renderer.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -497,19 +497,21 @@ export function WidgetRenderer({ title, description, html }: WidgetRendererProps
497497
}
498498

499499
// Initialize the iframe shell once when html first appears.
500-
// After that, stream content updates via postMessage — no iframe reload.
500+
// Shell loads EMPTY so partial streaming fragments (e.g. unclosed <style>)
501+
// can't break the bridge script. All content is streamed via postMessage.
501502
useEffect(() => {
502503
if (!html || !iframeRef.current) return;
503504

504505
if (!shellReadyRef.current) {
505-
// First time: load the full document so the shell (styles, bridge JS) is ready
506506
shellReadyRef.current = true;
507-
committedHtmlRef.current = html;
508-
iframeRef.current.srcdoc = assembleShell(html);
507+
iframeRef.current.srcdoc = assembleShell();
509508
return;
510509
}
511510

512-
// Subsequent updates: stream content into existing iframe via postMessage
511+
// Wait for iframe to load before sending postMessage
512+
if (!loaded) return;
513+
514+
// Stream content into existing iframe via postMessage
513515
if (html === committedHtmlRef.current) return;
514516
committedHtmlRef.current = html;
515517

@@ -520,7 +522,7 @@ export function WidgetRenderer({ title, description, html }: WidgetRendererProps
520522
"*"
521523
);
522524
}
523-
}, [html]);
525+
}, [html, loaded]);
524526

525527
// Detect when html has stopped changing (streaming complete).
526528
// Resets a debounce timer on every html update — settles after 800ms of no changes.

0 commit comments

Comments
 (0)