Next.jsはページごとにレンダリング戦略を選択できる。fetch optionsやgenerateStaticParamsの有無で自動判定される。
// ── SSG (Static Site Generation) — ビルド時に静的HTML生成 ──
// generateStaticParams: 動的ルートのパスを事前に全部生成する
export async function generateStaticParams() {
const posts = await fetchAllPosts();
// [{ slug: 'post-1' }, { slug: 'post-2' }, ...] を返す
return posts.map(post => ({ slug: post.slug }));
}
// ── ISR (Incremental Static Regeneration) — 定期的に再生成 ─
// revalidate: N秒後にバックグラウンドで再生成する
export const revalidate = 60; // 60秒ごとに再生成
export default async function Page({ params }: { params: { slug: string } }) {
const data = await fetch('https://api.example.com/posts/' + params.slug, {
next: { revalidate: 60 }, // fetchレベルでも設定できる
}).then(r => r.json());
return <article>{data.content}</article>;
}
// ── SSR (Server-Side Rendering) — リクエストごとに生成 ────
// no-store: キャッシュしない → 毎回最新データを取得
export const dynamic = 'force-dynamic'; // ページ全体をSSRにする
export default async function Dashboard() {
const data = await fetch('https://api.example.com/dashboard', {
cache: 'no-store', // キャッシュ無効 = SSR
}).then(r => r.json());
return <div>本日の売上: {data.revenue}円</div>;
}
// ── CSR (Client-Side Rendering) — ブラウザで動的取得 ─────
// 'use client' でクライアントコンポーネントにする
'use client';
import { useState, useEffect } from 'react';
export default function UserProfile({ userId }: { userId: string }) {
const [user, setUser] = useState(null);
// useEffect でマウント後にデータを取得(CSR)
useEffect(() => {
fetch('/api/users/' + userId).then(r => r.json()).then(setUser);
}, [userId]);
return user ? <p>{user.name}</p> : <p>読み込み中...</p>;
}パフォーマンスの観点では SSG > ISR > SSR > CSR の順に有利。ただし更新頻度やパーソナライズの要件によって使い分ける。