📖
Next.jsのSSG / SSR / ISR の書き方(フェッチ単位)
fetch のオプションや next/cache のAPIで、ページ全体の dynamic/revalidate を書かなくても “その取得だけ” を SSG/SSR/ISR 相当にできます。
フェッチ単位の指定(App Router)
SSG 相当(静的キャッシュ)
// デフォルトがこれ(= Data Cache に保存)
await fetch('https://api.example.com/items', { cache: 'force-cache' });
- そのルートが動的要素(
headers(),cookies()など)を使っていなければ静的にキャッシュされます。 (Next.js)
SSR 相当(毎リクエスト)
// どちらか一方でOK(両方はNG)
await fetch('https://api.example.com/items', { cache: 'no-store' });
// または
await fetch('https://api.example.com/items', { next: { revalidate: 0 } });
- 「その
fetchだけ」キャッシュを使わず 毎回取得。 (Next.js)
代替:
noStore()を使うと、その処理スコープ全体を動的扱いにできます。
import { unstable_noStore as noStore } from 'next/cache';
noStore();
// …DBクエリや fetch など
(Next.js)
ISR 相当(時間で再検証)
// 60秒ごとにバックグラウンド再生成
await fetch('https://api.example.com/items', { next: { revalidate: 60 } });
- フェッチごとに有効期限を設定できます(ルート全体ではなく“この取得だけ”に適用)。 (Next.js)
タグでオンデマンド再検証(任意のタイミングで)
// 取得時にタグ付け
await fetch('https://api.example.com/items', { next: { tags: ['items'] } });
// サーバーアクション or Route Handler から無効化
import { revalidateTag } from 'next/cache';
revalidateTag('items');
- 該当タグのキャッシュを無効化→次アクセス時に再取得。 (Next.js)
注意点(重要)
-
cache: 'no-store'とnext: { revalidate: N }の同時指定は不可(衝突は無視され警告)。 (Next.js) -
headers()やcookies()を使うと、そのルートは動的レンダリング扱いになります。 (Next.js) - 同じルート内で複数
fetchに異なるrevalidateを指定した場合、最小の値が採用されることがあります。 (Next.js)
どこに書く?
- これらは Server Component(
page.tsx/layout.tsx内のサーバーコード)や Route Handler で記述します。 - Client Component では使えないため、必要なら「クライアント → Route Handler/Server Action を呼ぶ」構成にしてください。 (Next.js)
Discussion
noStore の説明に
とあります。この記事をふくめ、maro さまが投稿している他の記事は Next.js 14 を前提にしているのにもかかわらず、それが明示されていないと見受けられます。
最新情報を確認すること、もしくは Next.js 14 を前提にしている旨を明記することをお勧めします。