Hydration Proof

Search documentation

Find a page or section

Debugging hydration errors

From a vague console message to the line that caused it.

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:

  1. Use a clean browser profile. Open the page without extensions. If the error disappears, check browser extensions.
  2. Run a development build. It shows a component stack and, in React 19, a diff. Production errors may show only a number.
  3. Read the diff. + is the browser's value; - is the server's.
  4. Find the component. Follow the stack to a file you own.
  5. 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
-    Server

React 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 likeLikely cause
Two timestamps a few hundred milliseconds apartThe clock
The same time, hours apartTimezone
1,234.5 and 1.234,5Locale
Two random-looking tokensRandom values or ids
light and darkTheme
Desktop and mobile markupMedia queries
Different records or countsData
Class names like sc-a1b2 in a different orderCSS-in-JS

How to find which component causes a hydration error

When the diff is not enough, narrow it down:

  1. Follow the component stack. Start with the first component from your app.
  2. 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.
  3. Turn off JavaScript. Reload to see the page before React runs.
  4. 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.
  5. 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 / - Server legend (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:

  1. Build and start the app locally in production mode, with the server's timezone and locale.
  2. Turn on browser source maps (productionBrowserSourceMaps: true in Next.js) to map minified code to your files.
  3. Test development and production builds side by side and compare what each reports.

React hydration errors only in production walks through each step.

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 cause

With --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.