CONTACT US
TABLE OF CONTENTS

Next.js Rendering Strategies in 2026: SSR vs SSG vs ISR vs CSR

Text Next.js Rendering Strategies in 2026: SSR vs SSG vs ISR vs CSR in red and white on a dark background with abstract computer and window icons.

Every Next.js project runs into this decision eventually: which rendering strategy fits which page. Get it wrong and you pay for it in server costs, search visibility, or Core Web Vitals — sometimes all three.

Next.js 16 changed the calculus by making Cache Components and Partial Prerendering the default, which means the old “pick one strategy for your whole app” framing no longer applies.

Here’s how SSR, SSG, ISR, and CSR actually differ in 2026, when each is the right call, and how Cache Components let you combine them on a single page.

The Four Rendering Strategies at a Glance

StrategyWhen HTML Is BuiltSEO ImpactTypical CostBest For
SSROn every request, server-sideStrong — full HTML at request timeHigher — server computes per visitPersonalized or per-request data: search results, checkout
SSGAt build timeStrong — full HTML pre-renderedLowest — served from CDNMarketing pages, docs, rarely-changing content
ISRAt build time, then regenerated on an interval or on demandStrong — same as SSGLow — regenerates only when neededBlogs, product catalogs, content that changes but not per-second
CSRIn the browser, after JS loadsWeak — content arrives after JS executesLowest server cost, highest client costAuthenticated dashboards, internal tools where SEO doesn’t matter

The pattern worth internalizing: SSR, SSG, and ISR all send complete HTML, so search engines index them the same way. CSR is the outlier — a crawler has to execute JavaScript before there’s anything to read, which is slower and less reliable at scale. This also shows up in Core Web Vitals: Interaction to Next Paint (INP), a confirmed Google ranking signal, penalizes heavy client-side JavaScript execution, which is exactly what CSR depends on.

Infographic comparing four Next.js rendering strategies: Static Site Generation, Incremental Static Regeneration, Server-Side Rendering, and Client-Side Rendering, showing where HTML is built and SEO strength. Dark background, red and white text.

Server-Side Rendering (SSR)

SSR generates HTML on the server for every request. The visitor — and the crawler — gets complete, current markup immediately, and the page can reflect data that’s specific to that request: a logged-in user, a live price, a search query.

In the App Router, a route becomes dynamic (SSR) as soon as it reads request-time data — cookies, headers, search params, or an explicitly uncached fetch:

// app/products/[id]/page.tsx
async function getProduct(id: string) {
  const res = await fetch(`https://api.example.com/products/${id}`, {
    cache: 'no-store',
  });
  return res.json();
}

export default async function ProductPage({
  params,
}: {
  params: { id: string };
}) {
  const product = await getProduct(params.id);
  return <div>{product.name}</div>;
}

The tradeoff: the server does work on every visit, so cost and latency scale with traffic. Use SSR when data genuinely can’t be cached — not as a default.

Static Site Generation (SSG)

SSG generates HTML once, at build time, and serves it from a CDN. There’s no per-request server computation, so it’s the fastest and cheapest option to run — Time to First Byte is close to minimal, and the attack surface shrinks along with the infrastructure.

In the App Router, this is simply a fetch with default caching — no extra configuration needed:

async function getPosts() {
  const res = await fetch('https://api.example.com/posts'); // cached at build
  return res.json();
}

export default async function BlogPage() {
  const posts = await getPosts();
  return <PostList posts={posts} />;
}

The limitation: content is frozen until the next build. On a site with thousands of pages, or content that changes often, that means either long build times or stale pages — which is exactly what ISR exists to fix.

Incremental Static Regeneration (ISR)

ISR keeps SSG’s speed but regenerates individual pages in the background, either on a fixed interval or on demand, without rebuilding the whole site. It’s the right default for most content-driven pages: fast to serve, cheap to run, and never more than one revalidation cycle out of date.

async function getPosts() {
  const res = await fetch('https://api.example.com/posts', {
    next: { revalidate: 3600 }, // regenerate at most once per hour
  });
  return res.json();
}

For updates triggered by an event — a CMS publish, an inventory change — call revalidatePath() or revalidateTag() from a Server Action or webhook handler instead of waiting on the interval. That’s the on-demand half of ISR, and it’s what makes it viable for e-commerce and news, not just blogs.

Client-Side Rendering (CSR)

CSR sends a minimal HTML shell and builds the page in the browser with JavaScript. It’s the right model for authenticated, highly interactive surfaces where SEO is irrelevant — dashboards, admin panels, internal tools — because the user stays in one long session and speed-to-first-paint matters less than responsiveness after that.

'use client';
import { useEffect, useState } from 'react';

export default function Dashboard() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('/api/dashboard')
      .then((r) => r.json())
      .then(setData);
  }, []);

  return data ? <DashboardView data={data} /> : <Spinner />;
}

The cost: content only exists after JavaScript executes, which is slower and less crawler-friendly than the alternatives, and heavy client-side execution is a direct driver of poor INP scores.

CSR behind a login wall is a reasonable, deliberate choice. CSR as the default rendering strategy for a public, SEO-dependent page usually isn’t.

What Changed in Next.js 16: Cache Components and Partial Prerendering

Through Next.js 15, a route was either fully static or fully dynamic — there was no in-between.

Next.js 16 removes that constraint with Cache Components, which complete the Partial Prerendering (PPR) model first introduced in 2023: a single route can serve a static, pre-rendered shell immediately while genuinely dynamic parts stream in separately, without holding up the rest of the page.

Enable it with one flag:

// next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  cacheComponents: true,
};

export default nextConfig;

In practice, this means wrapping the request-time-dependent part of a page in Suspense, while everything else stays static:

export default function ProductPage({ params }: { params: { id: string } }) {
  return (
    <div>
      <ProductInfo id={params.id} /> {/* static shell */}
      <Suspense fallback={<InventorySkeleton />}>
        <LiveInventory id={params.id} /> {/* streamed in, dynamic */}
      </Suspense>
    </div>
  );
}

This is why the SSR-vs-SSG framing is incomplete on its own in 2026: on a single product page, the description and layout can be static (SSG/ISR), while live inventory or a personalized recommendation streams in dynamically (SSR-like), all without the old all-or-nothing tradeoff.

The strategies above are still the building blocks — Cache Components just mean you’re no longer forced to pick exactly one per route.

How to Choose: A Decision Framework

Page TypeRecommended StrategyWhy
Marketing / landing pagesSSG (or ISR if content is CMS-managed)Content rarely changes; maximum speed at the lowest cost
Blog / documentationISRUpdates without full rebuilds; still fully static between revalidations
E-commerce product pagesISR + Cache Components for live inventory/priceCatalog data is stable; inventory and price need to stay current
Search results / filtered listingsSSRQuery-specific output isn’t cacheable per fixed URL
Checkout / cartSSR, or CSR behind authPer-user, per-session; no SEO value to preserve
Authenticated dashboardsCSRNo SEO requirement; rich interactivity is the actual point

Default to ISR for anything content-driven unless there’s a specific reason not to.

SSR should be the exception you reach for when data truly can’t be cached — not the starting point — because it’s the only one of the four whose cost scales directly with traffic.

Applying This to Common Page Types

The framework above is easy to nod along to in the abstract. It gets more useful once you attach it to three architectures almost every team ends up building — because each one has a natural rendering fingerprint, and fighting it is where most of the wasted server spend actually comes from.

Dark-themed infographic illustrating One Page, Two Render Timelines at Once with a flowchart showing static and dynamic content rendering separately for a web page, comparing static shell vs. streamed data.

The marketing site: mostly static, and deliberately boring about it

A corporate or marketing site should be one of the cheapest, fastest things you run — the homepage, service pages, and blog have no business paying SSR’s per-request tax, because almost nothing on them is actually per-request. SSG or ISR carries essentially the whole site.

Common mistake: a contact form or personalized CTA banner convinces a team to make the entire page dynamic. The fix isn’t SSR for the route — it’s a small client component dropped into an otherwise static page, so one form doesn’t tax every visitor who never touches it.

The e-commerce catalog: static bones, live nerve endings

A product page is really two pages wearing one URL: the description, images, and reviews that barely change, and the stock count or price that can change by the minute. ISR handles the first half; Cache Components stream in the second half as a live “hole” in an otherwise cached shell.

Cart and checkout don’t belong in this conversation at all — they’re per-session, carry zero SEO value, and are better handled by SSR or CSR without dragging the rest of the site’s rendering strategy into the decision.

The internal dashboard: where CSR finally gets to be the right answer

Everywhere else in this article, CSR is the strategy you reach for reluctantly. An admin panel or analytics dashboard is the exception, not a compromise: nobody needs to find it on Google, users stay logged in for long stretches, and the interactivity is the entire product.

The slow-first-paint, weak-SEO tradeoffs that rule CSR out for a marketing page simply don’t apply behind a login wall — so this is the one place a full client-rendered app is the deliberate, correct default.

Quick self-check — is your current setup fighting its own architecture?

  • A marketing or blog route running SSR with no personalization on it
  • A product page fully dynamic just to show live stock for one widget
  • An internal dashboard built with SSR/SSG when nothing on it needs to be indexed

If any of those sound familiar, that’s usually a rendering strategy left over from before the page’s actual requirements were clear — not a deliberate choice.

Getting the Rendering Strategy Right the First Time

Here’s the uncomfortable version: most Next.js apps aren’t running the wrong rendering strategy because someone chose wrong.

They’re running whatever was default the day the project started, untouched since — an SSR route that’s been quietly billing per-request for a page that hasn’t changed in a year, a dashboard someone built as SSG because that’s what the last project used.

Next.js 16 raised the stakes on that inertia. When the decision lived at the app level, “good enough” was a reasonable place to stop. Now that it lives at the component level, every route you haven’t revisited is a small, compounding bill.

If you’re not sure which of your pages are paying for freshness they don’t need, that’s exactly the audit Pagepro runs. Talk to us before your next Core Web Vitals report finds it for you.

FAQ

What’s the difference between SSR and SSG in Next.js?

SSR generates HTML on the server for every request, so it can reflect data specific to that request. SSG generates HTML once at build time and serves the same static file to every visitor until the next deployment. Both produce complete HTML that search engines can index equally well; the difference is when the work happens and whether the output can vary per request.

Is ISR still relevant with Cache Components in Next.js 16?

Yes. Cache Components change how static and dynamic content combine within a single page, but ISR is still the mechanism for revalidating cached data on an interval or on demand. In Next.js 16, ISR-style caching and Partial Prerendering work together rather than replacing each other.

Does CSR hurt SEO?

It can. A pure client-side-rendered page sends a near-empty HTML shell, so a crawler has to execute JavaScript before there’s content to index — a slower, less reliable step than reading complete HTML directly, especially at scale. CSR is a reasonable choice for pages that don’t need to rank, such as authenticated dashboards.

Can you mix rendering strategies on the same page?

Yes — this is what Cache Components and Partial Prerendering are built for. A single route in Next.js 16 can serve a static, cached shell immediately while specific components stream in dynamically, so a page is no longer required to be entirely static or entirely server-rendered.

What is Partial Prerendering (PPR)?

PPR is the Next.js model that lets a single page serve a static, pre-rendered shell while dynamic sections — wrapped in Suspense — stream in separately once their data is ready. First introduced in 2023, it became the default behavior in Next.js 16 through Cache Components.

Which rendering strategy is best for e-commerce?

Usually ISR for product and category pages, since catalog content is stable but needs periodic updates, combined with Cache Components to stream in genuinely live data like stock levels or personalized pricing. Cart and checkout, which are per-session and carry no SEO value, are better served by SSR or CSR.

Rafał Dąbrowski

Rafał joined Pagepro in 2021 as a Senior React JS Developer, bringing with him a rapidly developed expertise in web development that began just two years earlier, in 2019. He is renowned for his deep understanding of React JS, a key tool in modern web development. His ability to harness the full potential of React JS has made him a pivotal figure in the development team.

Article link copied

Close button

Leave a Reply

* Required informations.