Rendering Models — CSR, SSR, SSG, ISR and RSC
IntermediateFive ways to turn a component into HTML, differing in where and when it runs. Choosing per route rather than per application is the thing Next.js actually gives you.
Overview
A plain React app has one answer: everything renders in the browser, after the JavaScript arrives. That is fine for a dashboard behind a login and wrong for a page Google needs to read or a phone needs to show quickly. Next.js lets each route pick — build a page once at deploy time, render it per request on the server, rebuild it periodically, or ship it to the client — and the App Router adds a fifth option where components run on the server and never ship their code at all. Knowing which model a route is using explains almost every surprise that follows.
The Five
Where the HTML comes from, and what each costs.
// CSR — Client-Side Rendering
// The server sends an empty div. React builds the page in the browser.
// + cheap to host, great for logged-in app screens
// - blank until JS loads, weak for SEO, slow on a mid-range phone
// SSG — Static Site Generation (build time)
// HTML produced once, at deploy, served from a CDN.
// + fastest possible, cheapest, perfect SEO
// - stale until the next deploy; not for per-user content
// Next: the default for a route with no dynamic data.
// ISR — Incremental Static Regeneration
// Static, but regenerated in the background every N seconds.
// + CDN speed with fresh-enough content
// - a user can see a stale copy for up to N seconds
export const revalidate = 3600
// SSR — Server-Side Rendering (per request)
// HTML built on the server for each request.
// + always fresh, personalised, SEO-friendly
// - a server round trip on every visit; you pay for compute
// RSC — React Server Components (App Router)
// Components that run ONLY on the server and stream their output.
// Their code — and the libraries they import — never reach the browser.
// This is the default in the App Router, not an opt-in.Choosing Per Route
The decision, and how each is expressed.
// A marketing page, a blog post, a concept page — content that is the
// same for everyone. Static, rebuilt on a schedule:
export const revalidate = 3600 // ISR
// or nothing at all -> pure static
// A dashboard, anything that reads the signed-in user:
// touching cookies() or headers() opts the route into dynamic rendering
const session = cookies().get('sid') // now rendered per request
// A live price, a leaderboard, anything that must never be cached:
export const dynamic = 'force-dynamic'
// An editor, a chart, anything highly interactive with no SEO value:
'use client' // ordinary client React
// The practical rule: start static. Reach for dynamic only when the
// page genuinely depends on the request — a cookie, a header, a
// search param, or data that must be current to the second.
// This is per ROUTE, not per app. A single Next application can serve
// a static landing page from a CDN, a per-request dashboard and a
// client-rendered code editor at the same time.Why RSC Changes the Calculation
The part that is genuinely new, and the number that makes the argument.
// A server component can await data directly. No useEffect, no
// loading state, no API route in between:
export default async function Page() {
const problems = await db.problem.findMany() // runs on the server
return <ProblemList problems={problems} />
}
// Three things follow, and they are the whole pitch:
// 1. The data fetch happens next to the database, not across the
// internet from a browser — no waterfall, no round trip.
// 2. The component's code is never sent to the browser. Import a
// 300KB markdown parser in a server component and the client
// bundle does not grow at all.
// 3. Secrets are safe here. This code cannot leak to the client,
// so an API key in a server component stays on the server.
// What you give up: no state, no effects, no event handlers, no
// browser APIs. Those need a client component — which is what the
// next concept is about.
// Mental model that keeps this straight:
// server components = the page's DATA and STRUCTURE
// client components = the page's INTERACTIVITYKey Points to Remember
- 1Next.js lets each route choose its rendering model instead of committing the whole app to one
- 2Static plus ISR gives CDN speed with controlled staleness; dynamic rendering costs a server round trip per visit
- 3Reading cookies, headers or searchParams opts a route into dynamic rendering automatically
- 4Server components run only on the server: they can await data directly and their code never reaches the browser
- 5Server components hold data and structure; anything with state, effects or event handlers must be a client component
Interview Questions
Sign in to ask AriaWhat is the difference between SSG, ISR and SSR?
What does a React Server Component give you that a client component cannot?
How would you decide the rendering strategy for a given page?
Ask Aria about Rendering Models — CSR, SSR, SSG, ISR and RSC
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.