Skip to the content.

Module 2: Rendering strategies · Lesson 3 of 7 · 3 min read

SSR: HTML per request, and the hydration bill

What server rendering buys, what it costs on every request, and the three mistakes agents make in SSR code: browser APIs, unescaped state, a fresh store.

What SSR is, precisely

With client-side rendering the browser receives an empty shell and waits for JavaScript to build the page. With SSR the server generates the full HTML for every request, and the browser can paint text and images immediately. The code is universal: the same components render under Node and in the browser, and the client then hydrates — attaches its event listeners to the HTML that is already there instead of rebuilding it.

The doc’s Redux-Saga example shows the whole sequence. Create a store for the request, dispatch the data request, store.dispatch(END) and await the saga task so every fetch has finished, renderToString inside the Provider, then embed store.getState() in the page as window.__PRELOADED_STATE__ ahead of the client bundle.

Three mistakes, in code an agent will write

  1. Browser APIs on the server. Reading window.innerWidth during render crashes Node, which has no window. Guard it, or move it into useEffect, which only runs in the browser.
  2. Unescaped serialised state. The safe line escapes <:

    window.__STATE__ = ${JSON.stringify(state).replace(/</g, '\\u003c')}
    

    Without the replace, a user-supplied string containing </script> closes the tag and whatever follows it runs. It is an XSS hole in the most innocent line on the page.

  3. A fresh store on the client. createStore(reducer) without the preloaded state renders different content from the server’s, so React discards the server HTML and renders again. You pay for SSR and get client rendering.

When not to use it

The skill’s DON’T list is the most useful part of any brief: don’t server-render highly personalised pages that nobody needs to find in search, don’t use SSR where SSG would work (static is faster), and don’t ignore the server CPU each request costs.

The practice quiz turns that into four briefs. A logged-in analytics dashboard is not an SSR page: nothing on it is crawlable and nothing is shared between users, so an app shell that streams data wins. A news homepage is SSR, but behind a short edge cache with stale-while-revalidate, because uncached SSR makes every reader in a traffic spike a server render. And the cost teams find late is cache invalidation and capacity: personalising the HTML splits the cache key per user and quietly turns a cached page into an uncached one.

Review checklist for agent-written SSR

  1. Data is fetched in the server-side step, before render, not in a client effect.
  2. Nothing reads window, document or localStorage during the server render.
  3. Serialised state escapes <.
  4. The client store is created from the preloaded state.
  5. The route is SEO-critical or dynamic enough to justify a render per request.

Encode it, then practise it

Agent Skill: server-ssr The SKILL.md that encodes SSR for a coding agent. Install it into your agent, or download it for any Agent-Skills-compatible runtime.
npx skills add grvpanchal/elegant --skill server-ssr
Download server-ssr SKILL.md

Practise it

Pick a rendering strategy

Four product briefs, four rendering decisions, and the cost each one hides.

quiz medium server 10 min Solved

Course contents (7 lessons)

Module 1: Routes and containers

  1. Containers: where data meets the UI done
  2. Router: the URL is state too done

Module 2: Rendering strategies

  1. SSR: HTML per request, and the hydration bill done
  2. SSG: render once at build time, cache it right done
  3. App shell: cache the frame, stream the data done

Module 3: The network edge

  1. Proxy: one origin, and why CORS stops done
  2. Session: where tokens live, and what logout means done