Skip to content

raw-apps: prevent + surface the silent blank-screen (unmounted #root)#9975

Draft
Guilhem-lm wants to merge 3 commits into
mainfrom
glm/fix-react-blank-app
Draft

raw-apps: prevent + surface the silent blank-screen (unmounted #root)#9975
Guilhem-lm wants to merge 3 commits into
mainfrom
glm/fix-react-blank-app

Conversation

@Guilhem-lm

@Guilhem-lm Guilhem-lm commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

AI-generated (or hand-written) React raw apps could render a blank screen with no error when index.tsx was written as a bare export default function App() {...} that never mounts anything. The preview harness bundles and executes index.tsx against an empty <div id="root"> but does not auto-render a default export — the entrypoint must itself call createRoot(document.getElementById('root')!).render(<App />). When it doesn't, the JSX lives inside an uncalled function, so nothing throws and the runtime-error overlay stays silent.

This PR tackles the failure mode from two sides:

  1. Prevent it — strengthen the raw-app AI prompt so the mount requirement is explicit.
  2. Surface it — when a build still renders nothing, show an info overlay in the editor that names the exact fix.

Changes

Prompt (prevention)

  • system_prompts/base/raw-app.md — rewrote the Entrypoint section: index.tsx is the bundling and mount entrypoint, MUST mount App into #root (React/Svelte/Vue snippets), and never be replaced with a bare component. Added a blank-screen debugging note.
  • frontend/src/lib/components/copilot/chat/app/core.ts — same mount-entrypoint guidance in the in-chat app system prompt's Frontend section.
  • Regenerated derived files via system_prompts/generate.py: prompts.ts, skills/raw-app/SKILL.md, cli/src/guidance/skills.gen.ts.

Overlay (detection)

  • frontend/src/lib/components/raw_apps/RawAppEditor.svelte — handle a new emptyRender message from the preview iframe and render an info Alert ("Nothing rendered") pointing at the missing createRoot(...).render(...) call. Mirrors the existing runtime-error overlay; cleared on next build.
  • Also handle renderAppeared — the preview retracts the hint if a slow app (async fetch, Suspense) mounts #root after the grace window, so a legitimate late render can't leave a false-positive overlay.
  • Both messages are emitted by the preview harness in the builder repo: windmill-labs/windmill-code-ui-builder#17. That change polls #root after each build and posts emptyRender when nothing mounted (suppressed if a runtime error already explained the blank screen), then watches for a late mount to post renderAppeared.
  • The host handlers here are dormant-safe until the builder tarball that emits these messages is pinned, so they land ahead of the artifact bump.

Screenshots

emptyrender-overlay

A bare-component index.tsx (export default App, no createRoot) builds successfully (see logs) yet mounts nothing — the "Nothing rendered" overlay names the fix.

Sequencing

The overlay only fires once the builder tarball emits emptyRender:

  1. Merge builder PR windmill-labs/windmill-code-ui-builder#17 → CI publishes a new tarball to R2.
  2. Bump frontend/scripts/ui_builder_artifact.json (new version + sha256) — follow-up commit on this PR.

Test plan

  • Generate a React raw app via copilot chat; confirm index.tsx includes createRoot(document.getElementById('root')!).render(<App />) rather than a bare component.
  • Confirm source↔generated consistency (grep the new wording in all three generated files).
  • Bare-component build shows the "Nothing rendered" overlay; overlay clears on a rebuild that mounts #root; runtime error suppresses it (browser-verified, see screenshot).
  • False-positive retraction (browser-verified against the running editor): late-mount build (#root filled at 1000ms) → overlay appears @612ms, retracts @1018ms via renderAppeared; permanently-empty build keeps the overlay; immediate render never shows it.

🤖 Generated with Claude Code

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 7, 2026

Copy link
Copy Markdown

Deploying windmill with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6512baf
Status: ✅  Deploy successful!
Preview URL: https://f0f827c5.windmill.pages.dev
Branch Preview URL: https://glm-fix-react-blank-app.windmill.pages.dev

View logs

Guilhem-lm and others added 2 commits July 8, 2026 13:18
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mirror the runtime-error overlay for the silent blank-screen case: when the
preview reports `emptyRender` (build ran cleanly but never mounted #root),
show an info Alert pointing at the missing createRoot(...).render(...) call.

The handler is dormant-safe until the builder tarball that emits `emptyRender`
is pinned, so it can land ahead of the artifact bump.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Guilhem-lm Guilhem-lm force-pushed the glm/fix-react-blank-app branch from ad80138 to 3edd3e6 Compare July 8, 2026 11:18
@Guilhem-lm Guilhem-lm changed the title docs: clarify raw-app index.tsx must mount App to avoid blank screen raw-apps: prevent + surface the silent blank-screen (unmounted #root) Jul 8, 2026
Handle the preview's `renderAppeared` message (posted when a slow app
mounts #root after the empty-render grace window) by clearing the
"Nothing rendered" hint, so a legitimate late render doesn't leave a
false-positive overlay.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant