tezvyn:

SSR State Hydration: Syncing Server and Client State

AI-drafted, machine-checkedSource: redux.js.orgadvanced

SSR hydration syncs server and client state to prevent UI errors. The server renders the page with initial data, then sends that data to the client to "hydrate" its own state store. The footgun is using a global store on the server, which leaks data.

WHY IT EXISTS: Server-Side Rendering (SSR) sends a fully-rendered HTML page from the server for a fast initial load. However, the client-side JavaScript must then take over to make the page interactive. If the client's initial state doesn't match the data used to render the HTML, the app sees a mismatch, triggering a full re-render and a jarring user experience. This is known as a hydration error.

THE MENTAL MODEL: Think of SSR hydration like sending a pre-assembled Lego model in a box. The server builds the model (renders the HTML) and also includes the exact instruction manual (the initial state). When the box arrives, the client uses the instructions to confirm the model is correct before making it interactive. If the instructions don't match the model, the client gets confused and has to rebuild it, defeating the purpose of pre-assembly.

HOW IT WORKS: On the server, for each incoming request, you create a new, isolated state store instance (e.g., a Redux store). You fetch data, populate the store, and render your components to an HTML string. Then, you serialize the store's state and embed it in the HTML, often in a <script> tag. On the client, your code reads this serialized state and uses it as the initial value for its own store before mounting the application. This ensures both server and client start from the exact same data.

WHEN TO USE IT: This pattern is essential whenever you combine SSR with a client-side state management library like Redux or Zustand. It's a standard practice in frameworks like Next.js. Any data fetched on the server that the client needs for immediate interactivity must be hydrated.

WHEN NOT TO USE IT: You don't need hydration for purely client-side rendered applications (SPAs), as there is no server state to sync with. It's also unnecessary for fully static pages where client-side interactivity doesn't depend on dynamic, server-fetched data.

ONE CANONICAL EXAMPLE: In a Next.js application, a server component fetches user data. To use this data in a client-side Redux store, you must create a store instance for that specific request on the server. You then pass the initial state to a client-side provider, which initializes the client's store with that same data. The biggest footgun is defining a global, singleton store on the server; it will be shared across concurrent user requests, leaking private data.

Read the original → redux.js.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.