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(), orsearchParamsforcing 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 buildand 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()orrevalidateTag()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):
- SSG — HTML from CDN edge, minimal compute, best TTFB globally.
- ISR (cache hit) — Same as SSG until revalidation; occasional slower request during regeneration.
- SSR (cached) — Good if you use CDN or data cache; poor if every request hits the database cold.
- 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
fetchresponses cached by default unless opted out. Control withcache,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:
- Does Google need to index this URL?
- Does the HTML change per user session?
- How often does data change?
- 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:
- Must this URL rank in search? No → CSR is fine behind login (dashboard, POS terminal, analytics). Yes → continue.
- Is content identical for all visitors? Yes → continue. No → SSR (or static shell + CSR island for private widgets).
- Does data change between deploys? No → SSG (portfolio, company site, blog with rebuild on publish).
- Does data change frequently but tolerate short staleness? Yes → ISR (products, listings, news).
- Must every request see live data? Yes → SSR with careful caching (admin reports, per-user CRM).
- 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
generateStaticParamsfor 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/dynamicandssr: falseonly 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 →
revalidatePathfor ISR catalogs. - Keep secrets and DB access in Server Components or Route Handlers only.
- Use environment-based
NEXT_PUBLIC_SITE_URLfor 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.