Home/Learn/Next.js/Rendering Models — CSR, SSR, SSG, ISR and RSC

Rendering Models — CSR, SSR, SSG, ISR and RSC

Intermediate
Foundations

Five 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.

Where and when the HTML is produced
// 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.

Start static; go dynamic when the request matters
// 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.

Fetch next to the data; ship less JavaScript
// 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 INTERACTIVITY

Key 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 Aria
1

What is the difference between SSG, ISR and SSR?

Medium
2

What does a React Server Component give you that a client component cannot?

Medium
3

How would you decide the rendering strategy for a given page?

Hard

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.

Loading discussion…