Hydration Proof

Search documentation

Find a page or section

An escape hatch for one element, not a way to silence a page.

suppressHydrationWarning hides a hydration warning for one element's text or attributes. It does not fix the difference. Use it only when that difference is expected, such as a live timestamp or a theme class set before hydration.

What suppressHydrationWarning does

React calls this prop an escape hatch. It applies to one element, not a whole component tree.

Its limits are:

  • It covers the element's own attributes and direct text, but not its child elements.
  • React does not fix the mismatched text for you. The server value can remain until another render updates it (hydrateRoot docs).
  • It cannot hide a structural difference, such as an element that exists on only one side.
components/current-date.tsx
"use client";
 
export function CurrentDate() {
  // The server's date and the browser's date can differ around midnight.
  return (
    <time suppressHydrationWarning>{new Date().toLocaleDateString()}</time>
  );
}

When is it safe to use?

Use it when the difference is expected and the initial server value is acceptable:

  • A timestamp or live clock whose first value does not need to be exact.
  • An <html> or <body> attribute that a theme script sets before hydration.

Do not use it to hide a wrong price, link, or label. The incorrect value may stay on the page. Instead, make the first render match. The causes guides and two-pass rendering show how.

Why is suppressHydrationWarning not working?

If the warning remains, check where you placed the prop:

  1. It is on a parent, and the difference is in a child. It only works one level deep.
  2. It is on a component, not an HTML element. <RelativeTime suppressHydrationWarning /> does nothing unless the component passes the prop to an element.
  3. The difference is structural. An element exists on one side only, or is a different element. React re-renders the tree regardless.
  4. The error is about invalid nesting. "In HTML, <div> cannot be a descendant of <p>" comes from the browser rewriting the HTML, which no prop can hide.
  5. It is on the wrong element. next-themes changes <html>, so the prop belongs on <html>, not on <body>.

Here, the warning comes from the <span>, not its parent <div>:

components/clock.tsx
"use client";
 
export function Clock() {
  return (
    // Does nothing: the text is inside the <span>, one level down.
    <div suppressHydrationWarning>
      <span>{new Date().toLocaleTimeString()}</span>
    </div>
  );
}
components/clock.tsx
"use client";
 
export function Clock() {
  return (
    <div>
      {/* Works: the prop is on the element that holds the text. */}
      <span suppressHydrationWarning>{new Date().toLocaleTimeString()}</span>
    </div>
  );
}

suppressHydrationWarning: Next.js root layout

In Next.js, theme libraries often change <html> before hydration. Put the prop on that element in the root layout, as shown in the shadcn/ui dark mode guide:

app/layout.tsx
import type { ReactNode } from "react";
import { ThemeProvider } from "@/components/theme-provider";
 
export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <ThemeProvider attribute="class" defaultTheme="system" enableSystem>
          {children}
        </ThemeProvider>
      </body>
    </html>
  );
}

This covers the attributes on <html>, not a theme icon deeper in the page. See theme hydration errors if a toggle still differs.

suppressHydrationWarning: React Router root

In React Router framework mode, app/root.tsx renders <html> through its Layout export. Add the prop there only if a script intentionally changes <html> before hydration. See the React Router root layout reference.

app/root.tsx
import type { ReactNode } from "react";
import { Links, Meta, Scripts, ScrollRestoration } from "react-router";
 
export function Layout({ children }: { children: ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <head>
        <meta charSet="utf-8" />
        <Meta />
        <Links />
      </head>
      <body>
        {children}
        <Scripts />
        <ScrollRestoration />
      </body>
    </html>
  );
}

Can you ignore, disable or hide a hydration error in Next.js?

There is no app-wide setting to turn off hydration errors in React or Next.js. The Next.js error guide describes local fixes: move a browser-only read to useEffect, skip server rendering for a component, or suppress one expected difference.

Hiding the message would not fix the page. React may already have rendered the affected tree again, and an attribute mismatch can remain silent in production while the server value stays in place.

Choose a fix for the actual difference:

  • Fix the cause. Each cause has a local fix; the React hydration error guide maps each message to one.
  • Render the part on the client only with a client-only component or next/dynamic with ssr: false.
  • Use suppressHydrationWarning on the one element whose value cannot match.
  • Ignore extension noise in tests, not in the app: a clean browser profile has no extensions, and hydration-proof has ignore rules for attributes you cannot control.

In a custom React setup, hydrateRoot's onRecoverableError option lets you handle the log. It does not change how React hydrates the page.

hydration-proof vs suppressHydrationWarning

suppressHydrationWarning controls one React warning. hydration-proof checks the page and lists differences, including suppressed ones:

suppressHydrationWarninghydration-proof
What it doesStops React reporting one element's attribute and text differencesLoads every route and compares the server HTML with the client render
ScopeOne element, one level deepEvery element on every tested page
The pageKeeps the server's valueUnchanged: nothing is added to your app
Hidden differencesInvisible from then onListed as HP6001, for information
Structural differencesNot hiddenHP6002: the prop cannot hide this
A prop with nothing to hideNot reportedHP6003: remove it before it hides a future bug

The ESLint rule audit-suppress-hydration-warning flags props placed on a component, on an element with child elements, or where there is no changing content. It allows <html> and <body> by default and checks Server Components too.