Server-rendered React pages
Improve the initial page experience by sending rendered HTML before client JavaScript finishes loading.
Zustand · Const
SSR renders a React app to HTML on the server, while hydration makes that markup interactive in the browser. The server and client must render matching output to avoid hydration errors.
SSR first renders the application into HTML on the server. The browser then calls React's hydrateRoot with the matching application tree, turning that static markup into an interactive client app; the server and client must produce identical output to avoid hydration errors.
ReactDOMClient.hydrateRoot(document, <App />)hydrateRoot.import ReactDOMClient from 'react-dom/client'
import { App } from './app.tsx'
ReactDOMClient.hydrateRoot(document, <App />)Hydrate the server-rendered document with the same React app tree on the client.
Improve the initial page experience by sending rendered HTML before client JavaScript finishes loading.
Convert server-produced markup into a working client application after the page loads.
Diagnose mismatches caused by different data or browser-only rendering logic.
SSR generates the initial component HTML on the server, and hydration makes that markup interactive in the browser. React's hydrateRoot is the documented client entry point.
Follow-up: What must be true for hydration to succeed? The client tree must produce the same output as the server tree, including rendered data and markup.
Use react-dom/server to render the application on the server and react-dom/client to hydrate it on the client. The client invokes hydrateRoot(document, <App />) with the application tree.
Follow-up: Why are both packages needed? Server rendering and client hydration are separate phases with different runtime responsibilities.
Hydration errors occur when server and client rendering differ. Common causes include browser-only APIs, typeof window checks in render logic, different data, or extra whitespace around the root markup.
Follow-up: How should browser-dependent behavior be handled? Keep the initial rendered output consistent, then apply client-only behavior after hydration.
hydrateRootreact-dom/serverreact-dom/clientSSRHydration