“Server‑side rendering is **not* the goal. Faster time‑to‑interactive, better SEO and predictable data is.”*
— Learning Patterns, Hallie & Osmani
1. What is Server‑Side Rendering?
Server‑Side Rendering (SSR) means generating the HTML for each request on the server, then sending that markup to the browser so the user sees meaningful UI before JavaScript finishes hydrating.
The sequence is:
- Request → browser asks for a page
- Render → server executes component tree to HTML
- Send → server returns HTML + critical assets
- Hydrate → client JavaScript attaches event listeners
SSR differs from Static Site Generation (HTML produced at build time) and purely Client‑Side Rendering (HTML generated after JS loads).
2. Classic React SSR (before frameworks)
npm i express react react-dom react-dom/server
// server.js – minimal SSR with Express
import express from "express";
import { readFileSync } from "fs";
import React from "react";
import { renderToString } from "react-dom/server";
import App from "./App.js";
const htmlTemplate = readFileSync("./index.html", "utf8");
const server = express();
server.get("*", (req, res) => {
const markup = renderToString(<App url={req.url} />);
const html = htmlTemplate.replace("<!--app-->", markup);
res.send(html);
});
server.listen(3000, () => console.log("SSR app ↘ http://localhost:3000"));
This works, but you must hand‑roll routing, code‑splitting, data‑fetch orchestration, streaming, and more.
3. Pros & Cons of SSR
| ✅ Pros | 🚧 Cons |
|---|---|
| First content paints fast on slow devices | Server must render on every request — cost & latency |
| SEO‑friendly (HTML visible to crawlers) | More complicated cache strategy than static generation |
| Consistent data (no layout shift from client fetching) | Adds coupling between server and client environments |
| Enables progressive streaming & React Suspense | Cannot fully leverage CDN edge unless cached |
4. SSR with Next.js
Next.js automates bundling, routing, code‑splitting and hot‑reloading while exposing two flavours of SSR:
4.1 Pages Router – getServerSideProps
// pages/index.jsx
export async function getServerSideProps() {
const res = await fetch("https://api.example.com/posts");
const posts = await res.json();
return { props: { posts } };
}
export default function Home({ posts }) {
return (
<main>
<h1>Latest posts</h1>
<ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>
</main>
);
}
Every request runs getServerSideProps; HTML streams back to the client.
4.2 App Router (Next 14 +) – Server Components & Streaming
// app/page.tsx (acts like a React Server Component)
import PostList from "./PostList"; // also a server component
export default async function Home() {
const posts = await fetch("https://api.example.com/posts").then(r => r.json());
return (
<>
<h1>Latest posts</h1>
{/* PostList can stream in parallel */}
<PostList initialPosts={posts} />
</>
);
}
The App Router uses React Server Components (RSC) and Suspense‐based streaming so HTML chunks arrive progressively.
5. React for the Server (RSC vs SSR)
React 19 stabilised Server Components, letting parts of the tree run only on the server — no JS shipped to the client.
// components/ServerChart.server.jsx
import db from "@/lib/db";
import Chart from "@/components/Chart"; // client component
export default async function ServerChart() {
const data = await db.sales.findMany();
return <Chart data={data} />;
}
-
.server.jsxexecutes on the server, can access secrets, returns serialized props. - Client receives just the final HTML for that chunk plus minimal hydration JS for purely interactive children.
This complements SSR: pages can statically stream and embed dynamic server logic.
6. Putting It All Together
- Small sites → prefer Static generation; sprinkle RSC for secure data.
- Content‑heavy, SEO‑critical apps → SSR via Pages or App router.
- Data‑intensive dashboards → mix SSR + RSC + streaming for best TTFB and interactivity.
7. Conclusion
Server‑Side Rendering has matured from hand‑rolled renderToString() scripts to first‑class primitives in Next.js 14 and React 19.
By combining SSR, React Server Components and streaming, you can deliver fast‑painting, SEO‑friendly, user‑centric experiences without drowning in complexity.
Inspired by principles in “Learning Patterns” — Hallie & Osmani, ch. 5 (Rendering Strategies).
Top comments (0)