Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
🟣 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.

StrategyWhen HTML is madeWhereExample page
SSGAt build time (once)Server, during npm run buildAbout, course pages
ISRAt build, then refreshed every N secondsServer, in the backgroundBlog, product list
SSROn every requestServerDashboard, search results
CSRIn the browser after JS loadsBrowserLive 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 }))
}
npm run buildonceHTML filessavedCDN / cachevisitor≈ 20 ms
SSG: the fastest possible page

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>
}
VisitorNext.js serverDatabaseGET /dashboard (cookie)query for this userrowsfresh personal HTML
SSR: fresh and personal, rendered every time

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>)
}
BuildHTML v10–10 minserve v1 (fast)after 10 minserve v1 + rebuildnext visitorgets v2repeat
ISR: static speed with fresh content

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?

Does the page use cookies(), headers(), connection()?yes → dynamic ƒDoes it read searchParams?yes → dynamic ƒAn uncached fetch or DB call per request?yes → dynamic ƒNone of thesestatic ○ / ● (+ revalidate = ISR)
Next.js checks your code automatically

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?

  1. 1Same for everyone and rarely changes → SSG
  2. 2Same for everyone but changes sometimes → ISR (revalidate)
  3. 3Different per user or per query → SSR (dynamic)
  4. 4Changes every second while the user watches → CSR inside a server page
Rule of thumb

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.
← Next.js Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

Next topicRoute Handlers (Build an API) Your progress: 20 / 37 (54%) · Lesson 21 / 37 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free