Hydration Proof

Search documentation

Find a page or section

HP6002: suppressHydrationWarning cannot hide a structural difference

HP6002 (suppression-hides-structure) means suppressHydrationWarning is set, but the elements inside still differ, so React re-renders them. How to fix it.

HP6002 (suppression-hides-structure) means an element is marked with suppressHydrationWarning, but the elements inside it differ between the server and the client. The attribute only covers the element's own text and attributes, one level deep, so React still re-renders that part. Fix the structural difference instead of suppressing it.

CodeHP6002
Namesuppression-hides-structure
Default severityError
GroupsuppressHydrationWarning audit
What it meanssuppressHydrationWarning only covers text and attributes one level deep; the elements inside still differ.

What the HP6002 suppression hides structure finding means

suppressHydrationWarning tells React to accept a different text or attribute value on one element. It does not cover:

  • elements inserted or removed inside the marked element;
  • a different tag in the same place;
  • text or attributes of its children.

When hydration-proof finds one of these inside a marked element, it reports this code:

suppressHydrationWarning is set here, but the elements inside differ between server and client, so React still re-renders them.

Differences in a descendant of a marked element get this note as evidence instead: "<div> has suppressHydrationWarning, but it only covers that element's own text and attributes, not this descendant."

It is an error: React still reports the mismatch and renders the branch again on the client, as with HP1010.

Likely causes

  • The attribute on a wrapper, with the changing value in a child: <div suppressHydrationWarning><span>{time}</span></div>.
  • A branch that renders different elements on the server and the client, such as a typeof window check, marked in the hope that the error goes away.
  • A list whose items differ between the two renders.

How to fix it

suppressHydrationWarning only covers the element's own text and attributes; fix the structural difference.

  1. If only a text value differs, move the attribute to the element that holds the text.
  2. If the elements differ, render the same elements on both sides and fill in the client-only part after mount.
components/clock.tsx
// Before: the text is in the <span>, the attribute is on the <div>
export function Clock() {
  return (
    <div suppressHydrationWarning>
      <span>{new Date().toLocaleTimeString("en-US", { timeZone: "UTC" })}</span>
    </div>
  );
}
components/clock.tsx
// After: the attribute is on the element whose text differs
export function Clock({ now }: { now: Date }) {
  return (
    <div>
      <span suppressHydrationWarning>
        {now.toLocaleTimeString("en-US", { timeZone: "UTC" })}
      </span>
    </div>
  );
}

For a whole branch that only exists in the browser, see client-only components.

Catch it with ESLint

audit-suppress-hydration-warning reports the attribute on an HTML element that has element children (tooDeep), the pattern behind most HP6002 findings.

Can you ignore it?

checks.suppressedWarnings: 'off' drops every HP6xxx finding, this one included, but React still re-renders the elements. Prefer the fix; if you must defer it, use an ignore.issues rule with a reason and an expires date (see ignoring findings).