To debug a hydration error, find the element that differs and compare what the server sent with what React first rendered in the browser. In React 19 development builds, the error includes a diff. In production, you may need to compare the server HTML and browser output yourself.
How to debug a hydration error, step by step
A React debug hydration error session can follow these five steps:
- Use a clean browser profile. Open the page without extensions. If the error disappears, check browser extensions.
- Run a development build. It shows a component stack and, in React 19, a diff. Production errors may show only a number.
- Read the diff.
+is the browser's value;-is the server's. - Find the component. Follow the stack to a file you own.
- Fix the cause. Use the two values to identify it, then test again.
Read the diff React prints
React 19 shows the mismatch in its component tree. This example comes from the React 19 release post:
Uncaught Error: Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if an SSR-ed Client Component used:
...
https://react.dev/link/hydration-mismatch
<App>
<span>
+ Client
- ServerReact 18 printed separate warnings instead, for example Warning: Text content did not match. Server: "Server" Client: "Client", followed by "Hydration failed because the initial UI does not match what was rendered on the server."
Use the values to narrow down the cause:
| The values look like | Likely cause |
|---|---|
| Two timestamps a few hundred milliseconds apart | The clock |
| The same time, hours apart | Timezone |
1,234.5 and 1.234,5 | Locale |
| Two random-looking tokens | Random values or ids |
light and dark | Theme |
| Desktop and mobile markup | Media queries |
| Different records or counts | Data |
Class names like sc-a1b2 in a different order | CSS-in-JS |
How to find which component causes a hydration error
When the diff is not enough, narrow it down:
- Follow the component stack. Start with the first component from your app.
- Compare the HTML and DOM. "View page source" shows the server HTML; DevTools Elements shows the current DOM. Search both for the text near the error.
- Turn off JavaScript. Reload to see the page before React runs.
- Narrow the component tree. Temporarily render half the children, then repeat with the half that still fails. A shared layout can affect every route; a page component affects only its route.
- Check shared UI. Look at headers, footers, cookie banners and theme toggles when several pages fail in the same way.
Rule out browser extensions
Password managers and grammar checkers can add attributes before React
hydrates. If the diff contains cz-shortcut-listen="true" or
data-new-gr-c-s-check-loaded and you did not write it, test without
extensions. See browser extension hydration errors.
Debug hydration errors in Next.js
When you debug a hydration error, Next.js adds its own tools on top of React's:
- The dev overlay. Since Next.js 15, hydration errors show the source code of the error with suggestions. Since Next.js 16.2, the overlay labels the diff with a
+ Client/- Serverlegend (Next.js 16.2 release notes). - The error page. Next.js links the message to its hydration error page, which lists the usual causes.
The overlay shows one page at a time, while you browse, in development. Next.js dev overlay compared covers what it does not see.
Debug hydration mismatch reports in production
Production builds may show only Minified React error #418, with no element
or diff. React 19 production builds may not warn about attribute differences
at all. To find the source:
- Build and start the app locally in production mode, with the server's timezone and locale.
- Turn on browser source maps (
productionBrowserSourceMaps: truein Next.js) to map minified code to your files. - Test development and production builds side by side and compare what each reports.
React hydration errors only in production walks through each step.
Let hydration-proof do the search
hydration-proof checks routes for these differences and shows the element, both values, a source line when available and a possible cause:
npx hydration-proof test
npx hydration-proof test --mode both # development and production builds
npx hydration-proof test --probe # prove the causeWith --probe, the tool reloads affected pages while changing one factor at
a time. If changing the clock, locale or another factor changes the finding,
the report marks that cause as proven. See probes.
While fixing a page, use npx hydration-proof dev to see findings in an
overlay and open the source line in your editor. See the
dev overlay.