963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
1.7 KiB
1.7 KiB
Hydration Errors
Diagnose and fix React hydration mismatch errors.
Error Signs
- "Hydration failed because the initial UI does not match"
- "Text content does not match server-rendered HTML"
Debugging
In development, click the hydration error to see the server/client diff.
Common Causes and Fixes
Browser-only APIs
// Bad: Causes mismatch - window doesn't exist on server
<div>{window.innerWidth}</div>;
// Good: Use client component with mounted check
('use client');
import { useState, useEffect } from 'react';
export function ClientOnly({ children }: { children: React.ReactNode }) {
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
return mounted ? children : null;
}
Date/Time Rendering
Server and client may be in different timezones:
// Bad: Causes mismatch
<span>{new Date().toLocaleString()}</span>;
// Good: Render on client only
('use client');
const [time, setTime] = useState<string>();
useEffect(() => setTime(new Date().toLocaleString()), []);
Random Values or IDs
// Bad: Random values differ between server and client
<div id={Math.random().toString()}>
// Good: Use useId hook
import { useId } from 'react'
function Input() {
const id = useId()
return <input id={id} />
}
Invalid HTML Nesting
// Bad: Invalid - div inside p
<p><div>Content</div></p>
// Bad: Invalid - p inside p
<p><p>Nested</p></p>
// Good: Valid nesting
<div><p>Content</p></div>
Third-party Scripts
Scripts that modify DOM during hydration.
// Good: Use next/script with afterInteractive
import Script from 'next/script';
export default function Page() {
return <Script src="https://example.com/script.js" strategy="afterInteractive" />;
}