skills/react-ssr-and-suspense-patterns/SKILL.md
React SSR hydration and Suspense patterns — prevent hydration mismatch, suppress expected mismatches, strategic Suspense boundaries. Use when fixing hydration errors, implementing streaming, or placing Suspense fallbacks.
npx skillsauth add ihj04982/my-cursor-settings react-ssr-and-suspense-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Patterns for hydration correctness, flicker prevention, and streaming granularity.
For client-dependent values (theme, user prefs from localStorage), inject a synchronous script before React hydrates.
Bad (breaks SSR):
const theme = localStorage.getItem('theme') || 'light'; // undefined on server
Bad (flickers):
const [theme, setTheme] = useState('light');
useEffect(() => {
const stored = localStorage.getItem('theme');
if (stored) setTheme(stored); // flash of wrong theme
}, []);
Good (no flicker, no mismatch):
function ThemeWrapper({ children }: { children: ReactNode }) {
return (
<>
<div id="theme-wrapper">{children}</div>
<script
dangerouslySetInnerHTML={{
__html: `
(function() {
try {
var theme = localStorage.getItem('theme') || 'light';
var el = document.getElementById('theme-wrapper');
if (el) el.className = theme;
} catch (e) {}
})();
`,
}}
/>
</>
);
}
Useful for theme toggles, user preferences, authentication states.
For values that are intentionally different on server vs client (random IDs, dates, locale/timezone), use suppressHydrationWarning.
Bad (noisy warnings):
<span>{new Date().toLocaleString()}</span>
Good:
<span suppressHydrationWarning>{new Date().toLocaleString()}</span>
Do not use this to hide real bugs. Apply only where server/client difference is deliberate.
Place Suspense boundaries to show wrapper UI immediately while data streams in. Don't let a single fetch block the entire page.
Bad (entire page blocked):
async function Page() {
const data = await fetchData(); // blocks everything
return (
<div>
<Sidebar /><Header />
<DataDisplay data={data} />
<Footer />
</div>
);
}
Good (layout renders immediately):
function Page() {
return (
<div>
<Sidebar /><Header />
<Suspense fallback={<Skeleton />}>
<DataDisplay />
</Suspense>
<Footer />
</div>
);
}
async function DataDisplay() {
const data = await fetchData();
return <div>{data.content}</div>;
}
Share promise across components:
function Page() {
const dataPromise = fetchData();
return (
<Suspense fallback={<Skeleton />}>
<DataDisplay dataPromise={dataPromise} />
<DataSummary dataPromise={dataPromise} />
</Suspense>
);
}
function DataDisplay({ dataPromise }: { dataPromise: Promise<Data> }) {
const data = use(dataPromise);
return <div>{data.content}</div>;
}
When NOT to use: Critical layout data, SEO content above the fold, small fast queries, or when layout shift is unacceptable.
suppressHydrationWarningsuppressHydrationWarning not masking real bugsdevelopment
Conduct WCAG 2.2 accessibility audits with automated testing, manual verification, and remediation guidance. Use when auditing websites for accessibility, fixing WCAG violations, or implementing accessible design patterns.
research
Generate high-entropy research (자료조사) and ideas (아이디어) using Verbalized Sampling to avoid mode collapse and maximize creativity and novelty.
development
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
documentation
Sync documentation from source-of-truth (package.json, .env.example). Generates CONTRIB.md, RUNBOOK.md. Use when updating project docs or after adding scripts/env vars.