0Pricing
React Academy · Lesson

Hydration Errors: Causes & Fixes

Identify mismatches between server and client HTML and fix them with suppressHydrationWarning.

Hydration Errors: Causes & Fixes is a free React Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the React Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Is a Hydration Error?

A hydration error occurs when React's server-rendered HTML doesn't match the virtual DOM React expects on the client. React logs a warning and re-renders the component from scratch, causing a flash.

Common Cause 1: Random Values

Using Math.random(), Date.now(), or crypto.randomUUID() during render produces different values on server and client.

// Bad — different on server vs client:
<div id={Math.random().toString()}>...</div>

// Fix — use useId() (stable across server/client):
import { useId } from 'react';
function Component() {
  const id = useId();
  return <div id={id}>...</div>;
}

Common Cause 2: Browser-Only APIs

Reading localStorage, window.innerWidth, or navigator in render crashes on the server or produces different values.

// Bad — localStorage doesn't exist on server:
<div>{localStorage.getItem('theme')}</div>

// Fix — read in useEffect (client-only):
const [theme, setTheme] = useState('light');
useEffect(() => {
  setTheme(localStorage.getItem('theme') ?? 'light');
}, []);

Common Cause 3: Date/Time Formatting

Locale-aware date formatting returns different strings on server (UTC/Node locale) and client (browser locale).

// Risky — locale may differ:
<time>{new Date().toLocaleDateString()}</time>

// Fix — use a consistent locale:
<time>{new Date().toLocaleDateString('en-US', { timeZone: 'UTC' })}</time>

Common Cause 4: Invalid HTML Nesting

React generates client HTML from the virtual DOM, but invalid HTML nesting (e.g., <p> inside <p>) causes browsers to restructure the DOM differently, causing mismatches.

// Bad — browser auto-closes the nested <p>:
<p>Outer <p>Inner</p> text</p>

// Fix — use <div> or correct semantic elements:
<div>Outer <p>Inner</p> text</div>

Common Cause 5: Conditional Rendering Based on State

Components that render differently based on client-only state (like user auth, screen width) mismatch because the server renders without that state.

// Bad — server renders 'Guest', client re-renders 'Alice' immediately:
<h1>{user?.name ?? 'Guest'}</h1>

// Fix — use a mounted guard to defer client-only rendering:
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
if (!mounted) return <h1>Guest</h1>; // match server output

suppressHydrationWarning

Use suppressHydrationWarning on elements where mismatches are intentional (e.g., timestamps formatted client-side). It suppresses the warning for that element only.

<time suppressHydrationWarning dateTime={isoDate}>
  {new Date(isoDate).toLocaleString()}
</time>

Dynamic Import with ssr: false

In Next.js, use dynamic(fn, { ssr: false }) to prevent a component from rendering on the server entirely — eliminating hydration mismatches for client-only components.

import dynamic from 'next/dynamic';

const ClientOnlyChart = dynamic(() => import('./Chart'), { ssr: false });

export default function Dashboard() {
  return <ClientOnlyChart />; // only renders in the browser
}

Debugging Hydration Errors

React 18 logs detailed hydration error messages in development showing the exact DOM node mismatch. Use the browser DevTools to inspect the server HTML vs the React tree.

useId for Stable IDs

useId() generates stable, unique IDs that are consistent between server and client renders — use it for id/htmlFor pairs and ARIA attributes.

function FormInput({ label }: { label: string }) {
  const id = useId();
  return (
    <div>
      <label htmlFor={id}>{label}</label>
      <input id={id} />
    </div>
  );
}

Testing for Hydration Errors

Run your Next.js app in development mode (npm run dev) and watch the browser console. Hydration mismatches appear as red warnings with component stack traces.

Quick Check

What is the best fix for a component that renders differently on server vs client due to reading from localStorage?

Recap

Hydration mismatches come from: random values, browser-only APIs, locale-sensitive formatting, invalid HTML nesting, and client-only conditional rendering. Fix with useId(), useEffect for client-only state, suppressHydrationWarning for intentional differences, and dynamic({ ssr: false }) for client-only components.

Frequently asked questions

Is the “Hydration Errors: Causes & Fixes” lesson free?

Yes — the full text of “Hydration Errors: Causes & Fixes” is free to read here on the web, and the React Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the React Academy course, upgrade to CoddyKit PRO.

What will I learn in “Hydration Errors: Causes & Fixes”?

Identify mismatches between server and client HTML and fix them with suppressHydrationWarning. You practise React Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start React Academy?

No prior experience is required. React Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Hydration Errors: Causes & Fixes” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this React Academy lesson?

Yes. Every React Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. How React SSR Works Under the Hood
  2. Hydration Errors: Causes & Fixes
  3. Selective Hydration & Streaming HTML
  4. Islands Architecture Pattern
← Back to React Academy