Skip to content

Commit 3163426

Browse files
committed
fix(renderer): render fresh instead of hydrating a prerender snapshot
The markup in #react-root is not a server render of the tree — prerender-crawl snapshots the app after it has mounted, fetched and run its effects, then injects that. The first client render has none of it, so hydration could never match and every page threw #418 before React discarded the DOM and rebuilt it anyway. Routes reporting console errors in the build log fell from 547/572 to 5/572.
1 parent b57d7cd commit 3163426

1 file changed

Lines changed: 9 additions & 6 deletions

File tree

‎renderer/+onRenderClient.jsx‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { hydrateRoot, createRoot } from 'react-dom/client';
2+
import { createRoot } from 'react-dom/client';
33
import { BrowserRouter } from 'react-router-dom';
44

55
export default async function onRenderClient(pageContext) {
@@ -10,9 +10,12 @@ export default async function onRenderClient(pageContext) {
1010
<Page {...(pageProps || {})} />
1111
</BrowserRouter>
1212
);
13-
if (container.innerHTML && container.children.length > 0) {
14-
hydrateRoot(container, tree);
15-
} else {
16-
createRoot(container).render(tree);
17-
}
13+
// The markup already in #react-root is not a server render of this tree — it
14+
// is a snapshot prerender-crawl took of the app *after* it had mounted,
15+
// fetched its data and run its effects. React's first client render has none
16+
// of that yet, so hydration could never match: every page threw "hydration
17+
// failed" (#418) and React discarded the DOM and re-rendered regardless.
18+
// Rendering fresh skips the doomed attempt. The snapshot still does its job —
19+
// it is what crawlers read and what paints before the bundle runs.
20+
createRoot(container).render(tree);
1821
}

0 commit comments

Comments
 (0)