Skip to content

Commit 6d3924e

Browse files
committed
docs(react-dom): add hydrateRoot hydration mismatch debugging guide
1 parent abe931a commit 6d3924e

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

src/content/reference/react-dom/client/hydrateRoot.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ This is important for the user experience. The user will spend some time looking
191191
The most common causes leading to hydration errors include:
192192
193193
* Extra whitespace (like newlines) around the React-generated HTML inside the root node.
194+
* Using non-deterministic values like `Date.now()` or `Math.random()` in rendering logic.
194195
* Using checks like `typeof window !== 'undefined'` in your rendering logic.
195196
* Using browser-only APIs like [`window.matchMedia`](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia) in your rendering logic.
196197
* Rendering different data on the server and the client.
@@ -531,3 +532,42 @@ root.render(App, {onUncaughtError});
531532
// ✅ Correct: pass options to createRoot.
532533
const root = hydrateRoot(container, <App />, {onUncaughtError});
533534
```
535+
536+
### Debugging hydration mismatches {/*debugging-hydration-mismatches*/}
537+
538+
If you see an error like "Hydration failed because the server rendered HTML didn't match the client.", it means the HTML from the server is different from what React renders first in the browser.
539+
540+
<ConsoleBlock level="error">
541+
542+
Uncaught Error: Hydration failed because the server rendered HTML didn't match the client.
543+
544+
</ConsoleBlock>
545+
546+
#### Common causes {/*common-causes*/}
547+
548+
* Values that change every time you render, like `Math.random()` or `Date.now()`.
549+
* Rendering that depends on browser-only globals like `window`, `document`, or `localStorage`.
550+
* Different data on the server and the client during the first render.
551+
* Data loading timing issues where server data and client data do not match.
552+
553+
#### Example mismatch {/*example-mismatch*/}
554+
555+
```js
556+
function App() {
557+
return <div>{Math.random()}</div>;
558+
}
559+
```
560+
561+
This renders a different value on the server and the client, so hydration fails.
562+
563+
#### Debugging checklist {/*debugging-checklist*/}
564+
565+
1. Open the browser console and find the first hydration warning.
566+
2. Look for changing values in render (`Math.random()`, `Date.now()`). Move them to server data or calculate them after hydration in [`useEffect`.](/reference/react/useEffect)
567+
3. Keep browser-only code out of render. Read `window`, `document`, and similar APIs in [`useEffect`](/reference/react/useEffect) or an event handler.
568+
4. Make sure the first client render uses the same data as the server render.
569+
5. If one mismatch is expected (for example, a timestamp), use `suppressHydrationWarning={true}` on that element.
570+
571+
#### Isolating the component {/*isolating-the-component*/}
572+
573+
If you still cannot find the issue, replace parts of the UI with simple static markup. Add components back one at a time until the warning comes back. The last part you added is usually where the mismatch is.

0 commit comments

Comments
 (0)