← All errors · Next.jsReact & Next.js rendering errors
Hydration failed because the initial UI does not match what was rendered on the server
Exact error
Error: Hydration failed because the initial UI does not match what was rendered on the server.
What it means
React rendered HTML on the server, then rendered again in the browser and got a different result. React cannot attach to mismatched markup, so it throws during hydration.
Likely causes
- Using browser-only values during render (window, localStorage, Date.now(), Math.random()).
- Invalid HTML nesting, e.g. a <div> inside a <p>, or <a> inside <a>.
- Locale/time-zone dependent formatting (toLocaleString) differing between server and client.
- Browser extensions modifying the DOM before React hydrates.
How to fix it
Check the console for the specific element React complains about and fix invalid nesting first.
Move browser-only values into useEffect so the first client render matches the server:
'use client'; import { useEffect, useState } from 'react'; export default function Clock() { const [now, setNow] = useState(null); useEffect(() => setNow(new Date().toLocaleTimeString()), []); return <span>{now ?? ''}</span>; }For a component that can only run in the browser, disable SSR for it:
import dynamic from 'next/dynamic'; const Map = dynamic(() => import('./Map'), { ssr: false });For an unavoidable single-element difference (e.g. a timestamp), use suppressHydrationWarning on that element only:
<time suppressHydrationWarning>{new Date().toISOString()}</time>Retest in an incognito window to rule out browser extensions.
Prevent this next time
- Add ESLint with eslint-config-next (includes the React Hooks rules) and fix warnings before shipping.
- Run `next build` in CI on every pull request so hydration and render errors surface before production.
Guide: catch outages before your users do.
FAQ
What does "Hydration failed because the initial UI does not match what was rendered on the server" mean?
React rendered HTML on the server, then rendered again in the browser and got a different result. React cannot attach to mismatched markup, so it throws during hydration.
What usually causes it?
Using browser-only values during render (window, localStorage, Date.now(), Math.random()). Invalid HTML nesting, e.g. a <div> inside a <p>, or <a> inside <a>. Locale/time-zone dependent formatting (toLocaleString) differing between server and client. Browser extensions modifying the DOM before React hydrates.
How do I fix it?
1. Check the console for the specific element React complains about and fix invalid nesting first. 2. Move browser-only values into useEffect so the first client render matches the server: 3. For a component that can only run in the browser, disable SSR for it: 4. For an unavoidable single-element difference (e.g. a timestamp), use suppressHydrationWarning on that element only: 5. Retest in an incognito window to rule out browser extensions.
Related errors
- ReferenceError: window is not defined
- Text content does not match server-rendered HTML
- You're importing a component that needs useState. It only works in a Client Component
Get new fixes weekly
No spam. Unsubscribe anytime. Privacy