ADVANCED REACTJS • LESSON 36 OF 36

Server Rendering and Hydration

Understand the handoff from server HTML to interactive React.

Read the explanation, run the worked code, then complete the practice lab in Assignments. This advanced lesson includes worked code and a dedicated practice lab.

Understand the idea

Server rendering produces HTML that a browser can display before the application becomes fully interactive. Hydration connects React to that existing markup and its event handlers. In a Vite client-only practice app, createRoot normally creates the UI; in a server-rendered framework, the framework owns the hydration entry point. Do not replace the Edupoly application’s entry point with a manual hydration call.

The server output and the first client render should agree. A timestamp, random value, browser-only storage read or locale-dependent string can differ across environments. Invalid HTML nesting can also make the browser repair the DOM before React hydrates it. Treat hydration warnings as bugs to investigate rather than hiding them with suppressHydrationWarning.

The example begins with a deterministic placeholder and reads the time zone only after mounting. That is appropriate for a small browser-specific enhancement, although it creates an extra render and may cause layout movement. For important data, serialize a consistent server value into the client instead. The distinction between Server Components and Client Components is separate from whether initial HTML was server-rendered; a Client Component in a framework can still contribute to that HTML.

Server creates deterministic HTML ↓ Browser displays HTML ↓ Client hydrates matching tree ↓ Effects add browser-specific data
Trace the values through each step before changing the code.

Run the example

Use a separate React practice project with a Node.js version supported by Vite. Create it once with these commands, then use its development URL. Do not paste this into the Edupoly website’s own source files.

npm create vite@latest react-practice -- --template react
cd react-practice
npm install
npm run dev

Replace src/App.jsx with the following complete example. Keep Vite’s generated src/main.jsx entry point.

src/App.jsx

import { useEffect, useState } from 'react';
export default function App() {
  const [zone, setZone] = useState(null);
  useEffect(() => {setZone(Intl.DateTimeFormat().resolvedOptions().timeZone);}, []);
  return <main><h1>Local time zone</h1><p>{zone ?? 'Detecting your time zone…'}</p></main>;
}

Expected result

The initial render is the same deterministic placeholder in every environment; after mounting, the browser’s time-zone name appears. In Vite this demonstrates the two render states, not server hydration itself.

Apply this to your assignments

Run the example in Vite, then inspect the server HTML and hydrated DOM of a separate server-rendered practice project. Compare an initial new Date() value with a serialized timestamp prop. Check invalid nesting and browser-only APIs when diagnosing a mismatch.

Practice starting point

Use the worked example above as your starting point.

Open Assignments for this lesson’s practice lab and acceptance checks.

Common mistakes

Do not use typeof window to choose different initial markup on server and client. Do not access localStorage during a server render. suppressHydrationWarning is not a general repair.

Check your understanding

  1. Predict the output before running the example, then compare it with the result panel.
  2. Explain which value each expression reads and which action changes it.
  3. Try the boundary cases listed in the practice task and record what you observe.
  4. Rebuild one matching assignment without copying, then compare behavior with the original example.

Reference

Official documentation for this topic · Vite setup requirements