Client Component Hydration

Hydration is the browser-side process that connects JavaScript behavior to HTML that was already rendered on the server. In a Server Components architecture, it enables interactive Client Components to become usable without rebuilding the entire UI from scratch in the browser.

A server can send HTML that already represents the initial UI, allowing the browser to display useful content before the application's client-side JavaScript has finished loading. Hydration then lets the client-side framework associate that existing DOM with its component tree and attach the behavior required for interaction.

In a Server Components architecture, Server Components are rendered on the server and do not become interactive browser components. A Client Component is marked as client-side code and can use browser-only features such as event handlers and state. Its client-side JavaScript is sent to the browser so the framework can hydrate the relevant interactive UI.

Hydration is different from simply rendering HTML. Rendering creates the UI representation; hydration reuses existing server-generated DOM and establishes the client-side behavior and framework bookkeeping needed for interaction. This is why an application can display a button before its JavaScript is ready but still have a short period during which the button does not respond.

The server and client must agree about the initial rendered structure. If the client produces different markup during hydration—for example because rendering depends on `Date.now()`, random values, or browser-only state—the framework can report a hydration mismatch and may need to reconcile or replace parts of the DOM.

Good Server Components design keeps non-interactive work on the server and limits Client Components to interactive or browser-dependent boundaries. This can reduce the amount of JavaScript that must be downloaded and hydrated, while still providing interactive behavior where it is needed.

Key points

Interview questions

What is hydration?

Hydration is the process of making server-rendered HTML interactive in the browser. The framework uses the existing DOM rather than starting with an empty page. It connects the client-side component logic to that markup and establishes things such as event handling. After hydration, interactive components can respond to user actions.

How does hydration relate to Server Components?

Server Components are rendered on the server and do not themselves become interactive browser components through hydration. Client Components are the parts that need browser-side JavaScript for features such as state and event handlers. The server can render their initial UI, while the client receives the code needed to make those interactive boundaries work. Keeping the boundary small can reduce the amount of client-side JavaScript.

What is a hydration mismatch?

A hydration mismatch occurs when the client-side rendering result does not match the HTML that was produced by the server for the same initial UI. For example, using a time-dependent value during rendering can produce different text on the server and client. Frameworks can warn about the mismatch and may need to reconcile the affected DOM. The fix is usually to make the initial render deterministic or move client-only behavior to an appropriate client-side phase.

Why can a server-rendered button be visible but not clickable immediately?

The browser can display the server-generated HTML before the relevant client-side JavaScript has finished loading and hydrating. The button therefore exists visually, but its event handler may not yet be connected. This creates a period sometimes described as a hydration or interactivity gap. Once the client-side code is ready and the component is hydrated, the button can respond normally.

How would you minimize unnecessary hydration in a Server Components application?

I would keep non-interactive UI in Server Components and introduce Client Components only where browser-side state, event handlers, or browser APIs are required. I would avoid turning a large parent tree into a Client Component just because one small child needs interactivity. I would also inspect the resulting client bundle and component boundaries to identify unnecessary JavaScript. The goal is to preserve server rendering while keeping the hydrated interactive surface focused.