1. Conclusion: Why Do We Need Client Components?
The reason why you need to specify 'use client' (Client Component) when using localStorage, sessionStorage, window, or document in Next.js is that these are “Browser APIs” that only exist within the browser (client-side).
Under the “Server Component” environment where code is executed on the server, these objects do not exist (undefined), which triggers a runtime error the moment they are accessed.
2. Mechanism: The Difference in “HTML Rendering” Between Server and Browser
Even though we say “rendering HTML on the server (SSR)”, the underlying mechanism is completely different between the server-side and the browser-side.
| Key Differences | Server-side (Next.js SSR) | Browser-side (Traditional JS / Post-Hydration) |
|---|---|---|
| Environment | Node.js (Server Environment) | Web Browser (Chrome/Safari, etc.) |
| Operation | Converts JSX into plain “String (Text)” | Generates actual “DOM Objects” |
| Primary Method | React’s internal string rendering engine | DOM APIs like document.createElement() |
| window / document | Not Defined | Defined |
Server-Side Rendering Concept
The server does not manage a live UI screen like a browser does. It simply takes your JSX and concatenates it into a single, long string.
// Conceptual image (Actual logic is more complex)
let html = "";
html += "<div>";
html += "<h1>" + props.title + "</h1>";
html += "</div>";
return html; // Result: "<div><h1>Title</h1></div>" as a plain string
Since it is merely performing string addition at this stage, the document object is neither required nor present.
3. The Lifecycle: From SSR to Screen Display
-
[Server] String Compilation
Next.js analyzes components, generates the HTML “string”, and sends it to the browser.
-
[Browser] Parsing HTML
The browser reads the incoming HTML string. At this exact moment, the
windowanddocumentobjects are created inside the browser, and the text or images instantly appear on the screen (though interactive elements like buttons don’t work yet). -
[Browser] Hydration
The JavaScript that arrives later executes in the browser, attaching dynamic event listeners (like button clicks) to the pre-rendered HTML (DOM).
Next.js’s 'use client' (Client Component) directive is essentially a declaration stating, “This code should also run during steps 2 and 3 (browser-side).” This is why switching to a Client Component allows you to safely access window and document.