Question presented to candidate: "What does server-side rendering actually give you in a React app, and when would you not bother?"
What a strong answer should cover:
- SSR runs your components on the server and sends real HTML, so the first response already contains content instead of an empty
<div id="root">. - The server render is one pass with no lifecycle: state is initial, effects never run, refs are never attached. Anything that touches the DOM must be moved into an effect.
- The HTML contains no event handlers. It is inert until the client bundle loads and hydrates it — SSR without hydration gives you a page that looks right and does nothing.
- The wins are first contentful paint on slow networks and devices, and crawlers and link previews that read HTML rather than executing scripts.
- The costs are real: server CPU per request, a more complex deployment, and code that must be safe to run without
windowordocument. renderToStringis the blocking, legacy API and does not support Suspense. The streaming APIs —renderToPipeableStreamon Node,renderToReadableStreamon web runtimes — are what production uses.- SSR does not make the page interactive sooner on its own; hydration still has to happen, and a large bundle can make time-to-interactive worse than CSR.
- Skip it for authenticated dashboards behind a login, internal tools, and anything where nothing is public and every user has a fast machine.
Clarifying questions expected:
- "Is this content public and crawlable, or behind authentication?" — that usually decides it.
- "Which metric are we actually trying to move: first paint, or interactivity?"
Code / implementation expected: Optional. Naming the right server API and pairing it with hydrateRoot is the substance.