In short
With server-side rendering, the server builds the full HTML for each visitor before sending it. Users see real content straight away, and Google sees it too.
Server-Side Rendering — generating a page's HTML on the server for every request, so users (and crawlers) get fully-rendered content immediately.

Think of it like this
Dosa made fresh at the counter
At a busy darshini, your dosa is made only after you order, hot and exactly how you asked. It takes a minute, but it's fresh. SSR cooks the page per request, so it always shows the latest data for that user.
Watch it happen
Rendering /dashboard for one visitor
GET /dashboard
1/6The request arrives with the visitor's cookie, session=x9f.
The big ideas
What you need to know
HTML per request
Each visit runs your component on the server, fetches fresh data and sends finished HTML.
Triggered by request data
Reading cookies(), headers() or searchParams makes a route render per request, since output depends on the visitor.
Then hydration
The browser shows the HTML first, then React attaches event handlers so buttons work. That step is called hydration.
The trade-off
Always fresh and personal, but the server works on every visit, so it can be slower than a prebuilt page.
See it in code
Walk through the code
1// app/dashboard/page.tsx2import { cookies } from "next/headers";3 4export default async function Dashboard() {5 const cookieStore = await cookies();6 const token = cookieStore.get("session")?.value;7 8 const res = await fetch("https://api.example.com/me", {9 headers: { Authorization: `Bearer ${token}` },10 cache: "no-store",11 });12 const me = await res.json();13 14 return <h1>Welcome back, {me.name}</h1>;15}1/3cookies() is async in Next.js 15+, so await it, then read the session.
cookies() is async in Next.js 15 and later, so await it. Using it tells Next.js this page depends on the request and must render each time.
Save yourself the pain
Common mistakes
Oops
Using SSR for a page that's the same for everyone, like an About page.
Do this instead
If the content doesn't change per visitor, let it be static. It's faster and cheaper.
Oops
Calling cookies().get(...) without await in Next.js 15+.
Do this instead
Write const store = await cookies(), then store.get(...).
Your mission
Prove it's server-rendered
Quick check
What makes an App Router page render on every request?
Go deeper
- 1Build a page that fetches fresh data on every request using SSR.
- 2Compare SSR's per-request cost to SSG's build-time cost.
- 3Learn when SSR is the right choice: frequently changing, personalized data.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.