SSR, SSG, ISR, CSR, PPR
Where and when the page renders, what to pick in which context and how Next 16 infers the strategy.
Updated
What a "rendering strategy" means
Rendering = turning your components into HTML. The question is where and when it happens:
- where — on the server or in the browser;
- when — once, at build time; on every request; or once and then refreshed periodically.
Each combination is a strategy, with an acronym. The choice decides how fast the page appears, how fresh the data is, how much the server costs and how well Google sees it.
The strategies, in short
| Strategy | Where | When | Result |
|---|---|---|---|
| CSR — client-side rendering | the browser | after the JS loads | almost empty HTML; the JS builds the page |
| SSR — server-side rendering | the server | on every request | complete HTML, with fresh data |
| SSG — static site generation | the server | once, at build time | ready-made HTML files, served from a CDN |
| ISR — incremental static regeneration | the server | at build time or on the first visit, then refreshed periodically / on demand | static + fairly fresh data |
| PPR — partial prerendering | both | a static shell at build time + dynamic parts at request time, streamed | static and dynamic in the same page |
How each one feels
CSR — the user sees the content only at the end:
empty HTML→download the JS→fetch the data→the page appearsSSR — the content arrives ready from the server, but the server works on every request:
the server gets the data→complete HTML→the page appears→hydrationSSG / ISR — everything is ready in advance, on a CDN:
ready HTML on the CDN→the page appears instantly→hydrationHydration = React attaches the events to the HTML received from the server, so it becomes interactive.
A comparison
| CSR | SSR | SSG | ISR | PPR | |
|---|---|---|---|---|---|
| First paint | slow | medium | instant | instant | instant (the shell) |
| Fresh data | yes | yes | only at build time | almost | yes, in the dynamic parts |
| Per-user personalization | yes | yes | no | no | yes, in the dynamic parts |
| SEO | weak | good | excellent | excellent | excellent |
| Server cost | small | big | minimal | small | small |
When to use each
| Context | Strategy | Why |
|---|---|---|
| a blog, documentation, a landing page, marketing pages | SSG | the content rarely changes; maximum speed, SEO |
| a product catalog, news articles | ISR | many pages, changing now and then (price, stock) |
| a page that's static but has a per-user part (a cart, "welcome, Ana") | PPR | an instant shell + personalization |
| a dashboard, an inbox, an account — private, always fresh data | SSR (dynamic) | depends on the user on every request |
| an editor, a Figma / Excel-style app, a game | CSR for the interactive area | it's all local interaction; SEO is irrelevant |
| a search with filters | SSR for the first page + client for the filters | SEO + interactivity |
Most real apps combine strategies: static marketing, ISR products, a dynamic account, a client-side editor.
How they translate to Next.js 16 (App Router)
In the App Router you don't pick an acronym per page — Next infers the strategy from what the code uses:
| What you do in the code | Result |
|---|---|
nothing dynamic (or data in 'use cache') |
static (SSG) — ○ at build time |
'use cache' + cacheLife('hours') |
ISR — static, regenerated after the chosen duration |
generateStaticParams + dynamic routes |
SSG for the listed values, ISR for the rest on the first visit |
cookies(), headers(), searchParams inside <Suspense> |
PPR — ◐ at build time |
| the same APIs over the whole page, without a cache | dynamic SSR — ƒ |
| a Client Component fetching after mount / TanStack Query | CSR for that area |
This app: the lessons are in the static shell (generated at build time, hours cache), your progress arrives dynamically, streamed — PPR. The code editor is CSR (next/dynamic with ssr: false).
Automatic Static Optimization
A term from the Pages Router (the old router, the pages/ folder): if a page does not export getServerSideProps or getInitialProps, Next automatically pre-generates it as static HTML. In other words: static by default, dynamic only when you explicitly ask.
The App Router took the idea further: the inference happens per component, not per page — hence PPR. If you work on a project with pages/, you'll run into:
| Pages Router | Strategy |
|---|---|
| no data functions | automatic SSG (Automatic Static Optimization) |
getStaticProps |
SSG |
getStaticProps + revalidate: 60 |
ISR |
getServerSideProps |
SSR |
useEffect + fetch |
CSR |
Summary
- CSR = in the browser; SSR = on the server on every request; SSG = at build time; ISR = static, refreshed; PPR = static + dynamic in the same page.
- Public, rarely changing content → static / ISR; per-user data → dynamic / PPR; pure interaction → client.
- In Next 16 the strategy is inferred from the code:
'use cache', the runtime APIs and<Suspense>.