Skip to content

Prod non-SSR client mount: no error boundary, and mounting clears sibling DOM in the container #143

Description

@uhyo

Problem

Two related issues in prodMain (non-SSR branch) in packages/static/src/client/entry.tsx:

  1. Inconsistent wrapping. It is the only one of the four mount paths (dev/prod × SSR on/off) that renders without GlobalErrorBoundary and React.StrictMode:

    // SSR off: Root shell only, mount App client-side
    const browserRoot = <BrowserRoot />;
  2. Destructive mount. The App is mounted with createRoot(appMarker.parentElement).render(...). React clears all existing children of the container on the first render call. If a user's Root component renders static siblings around {children} — e.g. <body><Header/>{children}<Footer/></body> — those siblings are silently wiped when the client mounts. This works for the common "children are the sole content of <body>" shape, but the constraint is neither enforced nor documented.

Suggested fix

  • Wrap the non-SSR prod mount in GlobalErrorBoundary (and StrictMode) like the other paths.
  • For the container issue: either emit a dedicated wrapper element around the marker at build time and mount into that (so only the marker's own wrapper is ever cleared), or document the constraint clearly in the Root component docs.

Found during a framework audit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions