Skip to main content
MTS · Developer

SSG vs SSR vs ISR vs CSR in Next.js: Which Rendering Strategy Should You Actually Use?

Every week a team asks me to "make the whole app SSR" or "just static export everything." Both answers are usually wrong. Next.js App Router lets you pick a rendering strategy per route, and that is the superpower. I use all four modes in the same codebase — this portfolio is mostly SSG, a POS admin screen might be SSR, product listings often want ISR, and analytics dashboards stay CSR. Here is how I decide, with examples from real Next.js development projects.

16 min read · By Malik Taleeb Shahbaz · Updated 2026-07-13

Introduction

If you have read one "Next.js rendering" article that ends with "it depends," you are not alone. The frustrating truth is that it does depend — but not in a vague way. It depends on whether strangers need to find the page on Google, how often data changes, whether the user is logged in, and how much you are willing to pay in server compute.

Next.js is not one rendering mode. It is a router that lets you compose Server Components, Client Components, static HTML, dynamic HTML, and time-based revalidation in the same application. The App Router (Next.js 13+) made Server Components the default, which confused teams who learned Next.js through the Pages Router getServerSideProps / getStaticProps split. The mental model shifted: instead of picking a data function per page, you design component trees and caching boundaries.

This guide is for developers shipping real products — portfolios, POS systems, school management software, CRMs, marketing sites, and SaaS dashboards. I will compare CSR, SSG, SSR, and ISR the way I explain them on client calls: with examples, trade-offs, and a decision flow you can paste into your architecture doc.

Why rendering strategy matters

Rendering is where performance, SEO, infrastructure cost, and developer experience collide. Pick the wrong default and you will fight the framework for months.

What goes wrong when you guess

  • All CSR: Marketing pages do not rank, LCP suffers, social previews break.
  • All SSR: Server bills spike, TTFB grows under load, you cache nothing and wonder why Vercel costs jumped.
  • All SSG: Stale product inventory, personalized dashboards impossible without hacks.
  • ISR misconfigured: Users see outdated prices for an hour because revalidate was set to 3600 without on-demand hooks.

Rendering strategy is an architecture decision, not a tutorial checkbox. The teams that win treat each route as its own micro-product with its own freshness and visibility requirements.

I audited a school management startup that SSR'd every route — including the public homepage — because one developer copied a tutorial. Their homepage TTFB was 800ms on mobile. We moved marketing to SSG and kept the admin timetable view on SSR. Same codebase, no feature loss, hosting cost dropped roughly 40%.

Understanding CSR (Client-Side Rendering)

Client-Side Rendering means the browser downloads JavaScript, executes it, and builds the DOM. In React SPAs (Vite + React Router), essentially everything is CSR. In Next.js App Router, any component file with "use client" hydrates on the client — that is CSR for those subtrees.

How CSR works in Next.js 15

Server Components render on the server and send HTML. Client Components send HTML placeholders plus JavaScript bundles that hydrate interactivity. If you mark an entire page as a Client Component, you have turned that page into a mini-SPA for hydration purposes, even if the route itself was server-rendered once.

Real projects where CSR shines

  • Dashboard analytics: Charts, filters, date ranges — heavy interaction, no SEO.
  • Settings pages: Profile forms, notification toggles, API keys.
  • Notifications center: Real-time lists, mark-as-read, WebSocket updates.
  • Chat systems: Message threads, typing indicators, presence.
  • POS terminal UI: After staff login, barcode scanning and cart updates must feel instant; SEO is irrelevant.

CSR trade-offs

CSR feels fast after load. The first visit still pays the JavaScript tax. For public pages, that tax hits SEO and Core Web Vitals. Use CSR deliberately as islands, not as the outer shell of crawlable content.

Understanding SSG (Static Site Generation)

Static Site Generation pre-renders HTML at build time. Users receive files from a CDN edge — no Node server required per request. In the App Router, routes are static when they do not use dynamic server APIs and use cached data fetching.

How to make a route static in App Router

  • Use Server Components without cookies(), headers(), or searchParams forcing dynamic.
  • Use export const dynamic = 'force-static' when you want to be explicit.
  • For dynamic segments, implement generateStaticParams() — this portfolio's /blog/[slug] and /geo/[slug] routes do exactly that.
  • Run next build and confirm the output table shows ○ (Static) for your routes.

Real projects where SSG shines

  • Portfolio websites: Like this site — 28 prerendered routes, fast globally.
  • Company websites: About, services, contact — copy changes weekly, not every second.
  • Documentation: Versioned docs, MDX content, minimal server logic.
  • Marketing websites: Landing pages, pricing, feature grids.
  • Blogs: Articles published occasionally; rebuild or ISR on publish.

SSG is the highest ROI mode for Next.js SEO on content sites: crawlers get full HTML, TTFB is tiny, and hosting is cheap.

Understanding SSR (Server-Side Rendering)

Server-Side Rendering generates HTML on each request (or serves from a short-lived cache). Use it when the response must reflect request-specific or frequently changing data that cannot be predicted at build time.

What forces dynamic rendering in App Router

  • export const dynamic = 'force-dynamic'
  • Reading cookies or headers for personalization
  • fetch(url, { cache: 'no-store' }) or uncached database queries
  • Search results pages driven by query strings that must be server-rendered for SEO

Real projects where SSR shines

  • Admin dashboards: Role-based sidebars, per-tenant configuration.
  • POS back-office: Shift reports, staff permissions, store-specific pricing.
  • School management: Timetables and attendance filtered by term and campus.
  • CRM: Pipeline views with live deal stages from the database.
  • ERP modules: Inventory snapshots that must be current when the page loads.
  • User profile (semi-public): When content varies per session.

SSR is not "more professional" than SSG — it is more dynamic. Dynamic costs money and latency. Pay for it only where the product requires it.

Understanding ISR (Incremental Static Regeneration)

Incremental Static Regeneration combines static delivery with background updates. A page is static until its revalidation window expires; then the next request triggers a rebuild of that page.

ISR in Next.js 15 App Router

Set revalidation at the route or fetch level:

  • export const revalidate = 60 — regenerate at most once per 60 seconds per path.
  • fetch('https://api.example.com/products', { next: { revalidate: 300 } })
  • On-demand revalidation via revalidatePath() or revalidateTag() after CMS publish webhooks.

Real projects where ISR shines

  • News websites: Homepage refreshes frequently without full redeploys.
  • Product catalogs: Thousands of SKUs; rebuilding all pages on every stock change is wasteful.
  • E-commerce: Product detail pages with hourly price or availability updates.
  • Service listings: Directories, job boards, rental listings updated throughout the day.

ISR is the pattern many teams need but do not know the name for. They SSR product pages "to be safe" and pay 10x server cost compared to ISR with on-demand revalidation when inventory changes.

Performance comparison

Raw speed rankings for typical implementations (your mileage varies with discipline):

  1. SSG — HTML from CDN edge, minimal compute, best TTFB globally.
  2. ISR (cache hit) — Same as SSG until revalidation; occasional slower request during regeneration.
  3. SSR (cached) — Good if you use CDN or data cache; poor if every request hits the database cold.
  4. CSR (first load) — Waits on JS parse/execute; can be OK after code-splitting but rarely beats static HTML for LCP.

After first load

CSR and hydrated Client Components feel snappy for in-app navigation. That is why dashboards tolerate CSR. Public sites live or die on first load from Google Ads or organic search — optimize for cold visits.

Measuring Next.js performance

Run Lighthouse on throttled mobile, check WebPageTest filmstrips, and read Vercel Analytics or your APM. Compare the same page under SSG vs SSR with real data — not blog benchmarks. I ship app/sitemap.ts and static routes first, then add dynamic modes only where metrics prove the need.

SEO comparison

For Next.js SEO, crawlers want complete HTML, stable URLs, unique metadata, and fast loads. Ranking also needs content quality — rendering only removes technical blockers.

SEO by rendering mode

  • SSG / ISR: Excellent. HTML is immediate; Metadata API titles and descriptions are in the document. Best for public content.
  • SSR: Excellent for indexable dynamic routes (e.g. public profile URLs, filtered listing pages you want indexed).
  • CSR-only public pages: Poor default. Google can render JS, but it is slower and brittle for smaller teams.

Use the Metadata API in layout.tsx or page.tsx for titles, descriptions, Open Graph, and Twitter cards. Pair with JSON-LD, app/sitemap.ts, and app/robots.ts — not a hand-rolled static sitemap.xml you forget to update.

For deeper checklists, see SEO best practices for business websites and React vs Next.js for when CSR SPAs fight indexing.

Server cost comparison

Infrastructure cost scales with dynamic compute per request.

  • SSG: Lowest. CDN bandwidth only on many hosts.
  • ISR: Low. Occasional regeneration work; still mostly CDN.
  • SSR: Highest at scale. Every uncached request needs a serverless function or Node process.
  • CSR: Hosting can be cheap (static assets), but users pay in load time; API backends still cost money.

A viral marketing page on SSR can spike bills. The same page on SSG absorbs traffic like a CDN sponge. A POS admin SSR report used by twelve store managers is fine; a public homepage SSR'd for a million visitors is not.

Caching differences

Next.js 15 caching is explicit and sometimes surprising. Understand the layers:

Full Route Cache
Static routes stored at build time. SSG and ISR static output live here.
Data Cache
fetch responses cached by default unless opted out. Control with cache, next.revalidate, and tags.
Request Memoization
Deduplicates identical fetch calls within one request — not across users.
Router Cache (client)
Client-side RSC payload cache during navigation — affects UX, not SEO crawlers.

Practical caching rules

  • Marketing content: cache aggressively (SSG or long ISR).
  • User-specific dashboards: cache: 'no-store' or dynamic rendering.
  • Catalog pages: ISR + on-demand revalidation when products change.
  • Never cache personalized HTML at the CDN without varying on cookies — you will leak data.

Core Web Vitals impact

Google's Core Web Vitals tie ranking and UX to measurable thresholds.

LCP (Largest Contentful Paint)

SSG/ISR usually win — hero images and headings are in the first HTML byte stream. CSR delays LCP until JS runs. Use next/image with priority on above-the-fold images only.

INP (Interaction to Next Paint)

CSR-heavy pages can score well on INP after hydration if bundles are small. Bloated Client Components hurt INP everywhere. Split interactive widgets; do not hydrate the entire layout.

CLS (Cumulative Layout Shift)

Rendering mode matters less than reserving image dimensions and font metrics. Server-rendered HTML with explicit width/height on media still wins for perceived stability.

Rendering strategy is one lever. Image optimization, font loading, and third-party script discipline are the others. I treat all three in SEO-optimized builds.

Which strategy should you choose?

Stop choosing globally. Map user journeys:

  1. Does Google need to index this URL?
  2. Does the HTML change per user session?
  3. How often does data change?
  4. How interactive is the UI?

If (1) is yes and (2) is no → lean SSG or ISR. If (2) is yes → SSR or CSR inside auth. If (4) is extreme → CSR islands. If (3) is "every few minutes" → ISR. If (3) is "real-time" → SSR or client fetch with loading states.

Full comparison table

Factor CSR SSG SSR ISR
SEO Poor for public pages Excellent Excellent Excellent
Performance (TTFB) Slower first load Fastest Moderate Fast (stale until revalidate)
Server load Low (static assets) Very low High Low–medium
Build time Low Grows with page count Low Medium (partial builds)
Caching Browser + API caches CDN indefinite Must configure; often none CDN + time/tag revalidation
Dynamic data Client fetches after load Build-time only Per request Stale-while-revalidate
Best use cases Dashboards, chat, settings Portfolio, docs, marketing Admin, CRM, personalized views News, e-commerce, catalogs
Advantages Rich interactivity Speed, cost, SEO Fresh per-request data Speed + fresher content
Disadvantages SEO, first paint Stale until rebuild Cost, latency Complexity, brief staleness

Decision flow: CSR vs SSG vs SSR vs ISR

Walk this flow top to bottom for each route:

  1. Must this URL rank in search? No → CSR is fine behind login (dashboard, POS terminal, analytics). Yes → continue.
  2. Is content identical for all visitors? Yes → continue. No → SSR (or static shell + CSR island for private widgets).
  3. Does data change between deploys? No → SSG (portfolio, company site, blog with rebuild on publish).
  4. Does data change frequently but tolerate short staleness? Yes → ISR (products, listings, news).
  5. Must every request see live data? Yes → SSR with careful caching (admin reports, per-user CRM).
  6. Is the page mostly interactive UI? Use Server Components for the shell; add CSR Client Components for charts, maps, and forms.

That is the entire game. Everything else is implementation detail.

Common mistakes developers make

Using SSR everywhere. Tutorial cargo-culting. Marketing pages do not need per-request HTML.

Using CSR for SEO pages. Landing pages built as pure Client Components with empty initial HTML. Fix: Server Component page + small client islands.

Ignoring caching. Uncached database queries on SSR pages under load. Fix: revalidate, React cache(), or move to ISR.

Poor metadata. One generic <title> for all routes. Fix: Metadata API per page — see lib/metadata.ts patterns.

Missing sitemap. Crawlers discover pages slowly. Fix: dynamic app/sitemap.ts from your content source.

Missing robots.txt. Fix: app/robots.ts with sitemap reference.

Not optimizing images. Hero JPEGs at 4000px width kill LCP. Fix: next/image, AVIF/WebP, sizes attribute.

Ignoring Core Web Vitals. Shipping 400KB Client Components to every route. Fix: analyze bundle, dynamic import heavy charts.

"use client" at the root. Wrapping entire layouts in Client Components throws away RSC benefits.

Choosing ISR without a revalidation plan. Stale prices during sales events. Fix: on-demand revalidatePath from webhooks.

Best practices for Next.js 15 App Router

Architecture

  • Default to Server Components; push "use client" to leaves of the tree.
  • Colocate data fetching in Server Components; pass serializable props to clients.
  • Use generateStaticParams for all known dynamic slugs (blog, products, docs).
  • Document rendering mode per route in README or ADR — future you will thank you.

Performance & SEO

  • Static marketing, dynamic product — split routes, not repos.
  • Lazy-load modals and charts with next/dynamic and ssr: false only when necessary.
  • Export metadata from every public page.tsx; include Open Graph and canonical URLs.
  • Generate sitemap and robots from code, not manual XML files.
  • Measure CWV before launch; set performance budgets in CI if the team is mature enough.

Operations

  • Wire CMS/webhook → revalidatePath for ISR catalogs.
  • Keep secrets and DB access in Server Components or Route Handlers only.
  • Use environment-based NEXT_PUBLIC_SITE_URL for absolute URLs in metadata.

These are the patterns I use when shipping SaaS MVPs and business software — the SaaS development guide covers scope; this guide covers rendering.

Final decision guide

Project type Recommended rendering
Portfolio / company site SSG
Documentation SSG
Marketing / blog SSG or ISR on publish
E-commerce catalog ISR + on-demand revalidation
News site ISR
Admin / CRM / ERP SSR (auth) + CSR widgets
POS system (staff UI) CSR + API; public site SSG
School management SSR for reports; CSR for calendars
Analytics dashboard CSR
Chat / notifications CSR

Hybrid apps are normal. Unicorn projects that fit one mode are rare.

Conclusion

SSG vs SSR vs ISR vs CSR is not a popularity contest. Each mode trades freshness, cost, interactivity, and search visibility differently. Next.js App Router gives you all four in one codebase — the skill is assigning the right mode to each route.

Start static where you can. Add ISR when content churns. Reserve SSR for request-specific data. Isolate CSR to interactive surfaces. Measure Core Web Vitals, fix metadata, ship sitemap and robots from code, and stop letting tutorial defaults choose your architecture.

This portfolio is proof that SSG carries a full business site — home, services, projects, blog, geo pages — with excellent Next.js performance and no per-request server render. Your POS dashboard can live in the same repo as Client Components without forcing your homepage to SSR.

If you want help mapping routes for a real product — get in touch. I will tell you which pages should be static, which need ISR, and where CSR belongs, before you commit to the wrong pattern for six months.

What is the difference between SSG and SSR in Next.js?
SSG (Static Site Generation) builds HTML at deploy time and serves it from a CDN. SSR (Server-Side Rendering) generates HTML on each request when a user visits. SSG is faster and cheaper at scale for content that does not change every second; SSR fits personalized or highly dynamic pages.
What is ISR in Next.js?
Incremental Static Regeneration (ISR) keeps static pages fast but refreshes them on a schedule or on demand. You get CDN speed with content that updates without rebuilding the entire site. Common for product catalogs, news, and large e-commerce inventories.
When should I use Client-Side Rendering (CSR)?
Use CSR for authenticated, highly interactive UI where SEO does not matter — dashboards, settings panels, notifications, chat widgets. In the App Router, mark components with "use client" and keep the page shell server-rendered when possible.
Does SSR improve SEO compared to CSR?
For public pages that must rank on Google, yes. SSR and SSG deliver complete HTML to crawlers immediately. CSR-only pages rely on JavaScript execution, which is slower and easier to get wrong for indexing.
Can I mix SSG, SSR, ISR, and CSR in one Next.js app?
Yes, and you should. The App Router encourages per-route decisions. Marketing pages can be static, product pages ISR, user dashboards CSR inside a server layout, and admin reports SSR.
How does Next.js 15 App Router handle static pages?
Routes are static by default when they use only Server Components and do not call dynamic APIs like cookies(), headers(), or uncached fetch. Export const dynamic = 'force-static' or generateStaticParams makes intent explicit for dynamic segments.
Is ISR still relevant in Next.js 15?
Yes. Use revalidate in fetch options or export const revalidate on a page/route segment. ISR remains the sweet spot for large catalogs where full SSG rebuilds are too slow but SSR on every hit is too expensive.
What hurts Core Web Vitals in Next.js?
Oversized Client Components, unoptimized images, blocking third-party scripts, SSR without caching on high-traffic pages, and shipping the same huge JavaScript bundle to every route. Pick SSG or ISR for LCP-sensitive marketing pages.
Should a POS system use SSR or CSR?
Often both. Public marketing pages: SSG. Authenticated POS terminal UI: CSR or client-heavy islands for speed of interaction. Reports with sensitive per-user data: SSR or SSR with short cache disabled.
How do I choose between SSG and ISR for a blog?
Small blogs with infrequent posts: SSG at build time is simplest. Large blogs or multi-author sites with constant publishing: ISR or on-demand revalidation avoids redeploying for every article.