| 1 | # Hydration Errors |
| 2 | |
| 3 | Diagnose and fix React hydration mismatch errors. |
| 4 | |
| 5 | ## Error Signs |
| 6 | |
| 7 | - "Hydration failed because the initial UI does not match" |
| 8 | - "Text content does not match server-rendered HTML" |
| 9 | |
| 10 | ## Debugging |
| 11 | |
| 12 | In development, click the hydration error to see the server/client diff. |
| 13 | |
| 14 | ## Common Causes and Fixes |
| 15 | |
| 16 | ### Browser-only APIs |
| 17 | |
| 18 | ```tsx |
| 19 | // Bad: Causes mismatch - window doesn't exist on server |
| 20 | <div>{window.innerWidth |
| 21 | |
| 22 | // Good: Use client component with mounted check |
| 23 | ("use client"); |
| 24 | import { useState, useEffect |
| 25 | |
| 26 | export function ClientOnly({ |
| 27 | const [mounted, |
| 28 | useEffect(() => |
| 29 | return mounted ? |
| 30 | } |
| 31 | ``` |
| 32 | |
| 33 | ### Date/Time Rendering |
| 34 | |
| 35 | Server and client may be in different timezones: |
| 36 | |
| 37 | ```tsx |
| 38 | // Bad: Causes mismatch |
| 39 | <span>{new Date |
| 40 | |
| 41 | // Good: Render on client only |
| 42 | ("use client"); |
| 43 | const [time, setTime |
| 44 | useEffect(() => setTime |
| 45 | ``` |
| 46 | |
| 47 | ### Random Values or IDs |
| 48 | |
| 49 | ```tsx |
| 50 | // Bad: Random values differ between server and client |
| 51 | <div id={Math |
| 52 | |
| 53 | // Good: Use useId hook |
| 54 | import { useId } from 'react' |
| 55 | |
| 56 | function Input() { |
| 57 | const id = |
| 58 | return <input id |
| 59 | } |
| 60 | ``` |
| 61 | |
| 62 | ### Invalid HTML Nesting |
| 63 | |
| 64 | ```tsx |
| 65 | // Bad: Invalid - div inside p |
| 66 | <p><div>Content</ |
| 67 | |
| 68 | // Bad: Invalid - p inside p |
| 69 | <p><p>Nested</ |
| 70 | |
| 71 | // Good: Valid nesting |
| 72 | <div><p>Content</ |
| 73 | ``` |
| 74 | |
| 75 | ### Third-party Scripts |
| 76 | |
| 77 | Scripts that modify DOM during hydration. |
| 78 | |
| 79 | ```tsx |
| 80 | // Good: Use next/script with afterInteractive |
| 81 | import Script from "next/script |
| 82 | |
| 83 | export default function Page |
| 84 | return <Script |
| 85 | } |
| 86 | ``` |