Next.js supports multiple rendering strategies. Choosing the right one affects performance, SEO, and freshness of your content.

Overview

Strategy Acronym When HTML is generated Best for
Static Site Generation SSG Build time Blogs, docs, marketing pages
Server-Side Rendering SSR Every request Personalized, real-time data
Incremental Static Regeneration ISR Build time + periodic refresh Large catalogs, news feeds
Client-Side Rendering CSR In the browser Dashboards, authenticated apps

Static Site Generation (SSG)

Pages are pre-rendered at build time and served as static HTML.

  // app/about/page.tsx — static by default
export default function AboutPage() {
    return <h1>About Us</h1>;
}
  

Run npm run build — Next.js generates HTML files served instantly from a CDN.

Data fetching with default cache also produces static pages:

  export default async function BlogPage() {
    const posts = await fetch('https://api.example.com/posts').then(r => r.json());
    return <PostList posts={posts} />;
}
  

Server-Side Rendering (SSR)

HTML is generated on every request. Use when content must be fresh or personalized.

  export const dynamic = 'force-dynamic';

export default async function DashboardPage() {
    const session = await getSession();
    const data = await fetchUserData(session.userId, { cache: 'no-store' });
    return <Dashboard data={data} />;
}
  

Triggers for dynamic rendering:

  • export const dynamic = 'force-dynamic'
  • fetch(..., { cache: 'no-store' })
  • Using cookies() or headers() from next/headers

Incremental Static Regeneration (ISR)

Static pages that automatically refresh after a time interval:

  export const revalidate = 60; // Regenerate at most every 60 seconds

export default async function ProductsPage() {
    const products = await fetch('https://api.example.com/products').then(r => r.json());
    return <ProductGrid products={products} />;
}
  

How ISR works: serve cached page → after interval, next request triggers background regeneration → subsequent requests get updated content.

Client-Side Rendering (CSR)

Interactive parts render in the browser via Client Components:

  'use client';

import { useEffect, useState } from 'react';

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

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

    if (!data) return <p>Loading chart...</p>;
    return <Chart data={data} />;
}
  

Use CSR for highly interactive UI that does not need SEO.

Streaming and Suspense

Next.js streams HTML progressively. Wrap slow components in <Suspense>:

  import { Suspense } from 'react';

export default function Page() {
    return (
        <main>
            <h1>Dashboard</h1>
            <Suspense fallback={<p>Loading stats...</p>}>
                <SlowStatsComponent />
            </Suspense>
        </main>
    );
}
  

Choosing a Strategy

  Same content for all users?
├── Yes → Can it be stale for minutes/hours?
│   ├── Yes → SSG or ISR
│   └── No  → SSR
└── No (personalized) → SSR or CSR for interactive parts
  

During npm run build, check the route table: Static, λ Dynamic (SSR), ISR.

Next: build API endpoints with Route Handlers.