Hydration Proof

Search documentation

Find a page or section

Handle an intentional hydration mismatch

Some differences are fine. Make sure you know which ones you hid.

An intentional hydration mismatch is a difference you have chosen to allow, such as a live clock or a theme class set before hydration. Put suppressHydrationWarning only on the affected element. Then check the report to see exactly what it hides.

Symptoms

React may show no warning. hydration-proof still lists the difference:

CodeSeverityMeaning
HP6001infoA difference hidden by suppressHydrationWarning, with both values
HP6002errorThe attribute cannot hide this: the elements inside differ
HP6003infoNothing on the element differs, so the attribute hides nothing today

If a hidden difference does not look intentional, HP6001 becomes a warning and shows the likely underlying cause. Review it before accepting it.

What suppressHydrationWarning does

suppressHydrationWarning hides a warning for one element's own text and attributes. It does not fix the value. React describes it as an escape hatch in its DOM reference.

The server value can remain until another render changes it. Child elements are not covered.

Which intentional hydration mismatch is safe?

DifferenceSuppress it?
A live clock or "last updated" time that updates right after hydrationYes, on the element that shows the time
The theme class a pre-hydration script sets on <html>Yes, on <html> only
Attributes browser extensions add to <body>Only if the development warning gets in your way
Data, ids, CSS-in-JS class names, invalid nestingNo: fix the cause

If the difference should not exist, fix its cause. See common causes.

How to fix it

Put it on the smallest element

Put the prop on the element that actually differs, not a wrapper:

clock.tsx
// Before: the changing text is inside the <span>, not the <div>.
export function ClockBefore() {
  return (
    <div suppressHydrationWarning>
      <span>{new Date().toLocaleTimeString("en-US", { timeZone: "UTC" })}</span>
    </div>
  );
}
 
// After: the prop is on the element with changing text.
export function Clock() {
  return (
    <div>
      <span suppressHydrationWarning>
        {new Date().toLocaleTimeString("en-US", { timeZone: "UTC" })}
      </span>
    </div>
  );
}

On a component, the prop works only if the component forwards it to an HTML element.

Fix structural differences instead

The prop cannot hide an added, removed, or replaced element. Fix the structure instead. hydration-proof reports that case as HP6002.

Remove it where nothing differs

HP6003 means there is nothing to suppress today. Remove the prop so it cannot hide a future problem.

Prefer rendering after mount

You can often avoid suppression by rendering a stable placeholder first and updating after hydration. See two-pass rendering and when suppression is safe.

Catch it with ESLint

audit-suppress-hydration-warning flags props on components, static content, or a wrapper with child elements. It allows <html> and <body> by default and also checks Server Components.

npm install -D eslint-plugin-hydration-proof

Catch it in CI

hydration-proof test lists suppressed differences with both values. Check that each one is expected. A structural difference, HP6002, fails the run.

npx hydration-proof test

To change only the test report, use an ignore option rather than changing React's behavior. See ignoring findings.