🟣 Data, Server & APIs · Lesson 20
SSG, SSR & ISR Rendering
Four ways to make HTML
"Rendering" means turning your components into HTML. The question is when and where that happens.
| Strategy | When HTML is made | Where | Example page |
|---|---|---|---|
| SSG | At build time (once) | Server, during npm run build | About, course pages |
| ISR | At build, then refreshed every N seconds | Server, in the background | Blog, product list |
| SSR | On every request | Server | Dashboard, search results |
| CSR | In the browser after JS loads | Browser | Live clock, chat widget |
SSG – Static Site Generation
JSX – static pages
// app/about/page.jsx — no request data → static (built once)
export default function About() {
return <h1>About EduSite – since 2018</h1>
}
// app/courses/[slug]/page.jsx — static pages for every slug
export function generateStaticParams() {
return courses.map((c) => ({ slug: c.slug }))
}SSR – Server-Side Rendering
JSX – dynamic page
// app/dashboard/page.jsx — reads cookies → dynamic (rendered per request)
import { cookies } from 'next/headers'
export default async function Dashboard() {
const store = await cookies()
const name = store.get('student')?.value ?? 'Guest'
return <h1>Welcome back, {name}</h1>
}ISR – Incremental Static Regeneration
JSX – static + revalidate
// app/blog/page.jsx — static, but rebuilt at most every 10 minutes
export const revalidate = 600
export default async function Blog() {
const res = await fetch('https://cms.example.com/posts', { next: { revalidate: 600 } })
const posts = await res.json()
return posts.map((p) => <h2 key={p.id}>{p.title}</h2>)
}CSR – Client-Side Rendering
JSX – components/Clock.jsx
// components/Clock.jsx — rendered and updated in the browser
'use client'
import { useEffect, useState } from 'react'
export default function Clock() {
const [now, setNow] = useState('')
useEffect(() => {
const id = setInterval(() => setNow(new Date().toLocaleTimeString('en-IN')), 1000)
return () => clearInterval(id)
}, [])
return <span>{now}</span>
}What makes a route dynamic?
Reading the build output
After npm run build, Next.js prints a symbol for every route. This is the EduSite project:
Output of npm run build (EduSite)
Route (app)
┌ ○ /
├ ○ /_not-found
├ ○ /about
├ ƒ /api/courses
├ ○ /blog
├ /blog/[slug]
│ ├ ● /blog/why-nextjs-for-websites
│ ├ ● /blog/python-vs-c-first-language
│ └ ● /blog/how-to-start-coding
├ ƒ /contact
├ ƒ /courses
├ /courses/[slug]
│ ├ ● /courses/c-programming
│ ├ ● /courses/python-ai
│ ├ ● /courses/web-development
│ └ ● [+3 more paths]
├ ○ /opengraph-image
├ ○ /robots.txt
└ ○ /sitemap.xml
ƒ Proxy (Middleware)
○ (Static) prerendered as static content
● (SSG) prerendered as static HTML (uses generateStaticParams)
ƒ (Dynamic) server-rendered on demand
/courses and /contact are ƒ because they read searchParams (?q=, ?course=). /api/courses reads the request URL. Everything else is pre-built.
Which one should I use?
- 1Same for everyone and rarely changes → SSG
- 2Same for everyone but changes sometimes → ISR (revalidate)
- 3Different per user or per query → SSR (dynamic)
- 4Changes every second while the user watches → CSR inside a server page
Common mistakes
- Reading
cookies()in the root layout → every page of the site becomes dynamic. - Making a blog SSR "to be fresh" → ISR gives the same freshness with static speed.
- Using CSR for main content → search engines may index an empty page.
Summary
- SSG = build time, ISR = build + timed refresh, SSR = every request, CSR = in browser.
- Request-time APIs (cookies, headers, searchParams) make a route dynamic.
- Read
○ ● ƒin the build output to verify.
✅ Practice
Build your project and note which routes are ○, ● and ƒ. Add await cookies() to the About page, rebuild and see it change to ƒ — then remove it.
Frequently Asked Questions
Which rendering is best for SEO?
SSG, ISR and SSR all send complete HTML, so all are good for SEO. SSG/ISR are fastest because the HTML is ready before the request. CSR is weakest for SEO content.
How does Next.js decide static or dynamic?
A route is static unless it uses request-time data such as cookies(), headers(), searchParams, uncached fetch, or connection(). Using any of these makes it dynamic.
Can one site mix SSG and SSR?
Yes. Each route is decided separately. A typical site has a static home page, ISR blog and dynamic dashboard.
