あかね
Next.js の静的/動的と CloudFront の保存
2026年10月28日
見出しはありません
要約を生成中...
CloudFrontに認証ページがキャッシュされていないかなど、キャッシュが適切にされているか確認するタスクをしている時のことです。
改めての学びがあったのでアウトプットします。
Cookieにaccess_tokenがある時に/sign_inにアクセスしたら、/homeへリダイレクトする。という処理が機能せず、sign_inにアクセスできるという挙動になっていることが確認できました。
/sign_inはCloudFrontにキャッシュされておりMiddlewareまで処理が到達していなかったことです。
CloudFrontは、最初のリクエストに返した応答を保存し、次の利用者にはサーバーを通さずに返します。キャッシュはURLを基準に判定され、ログイン情報などのCookieでは分けません。Cookie自体はオリジンサーバーまで届きます。
保存するかどうかは、サーバーが返す Cache-Control ヘッダーで決まります。
s-maxage=…:共有キャッシュに保存できる
private / no-store:共有キャッシュに保存しない
保存済みの応答はサーバーに届かないため、その応答ではMiddlewareも実行されません。
SSG(静的生成)は、ページのHTMLをビルド時に作り、リクエストごとに作り直さず使う方式です。fetchを使うかどうかとは別に、動的にする理由がなければページは静的になります。
静的ページにはNext.jsが s-maxage を付け、CloudFrontに保存できるようにします。
動的ページには private, no-store が付くため、共有キャッシュには保存されません。
静的・動的の判定はページ(URL)単位です。ページや親レイアウトのどこかで動的な機能を使うと、そのページ全体が動的になります。たとえば hoge/layout.tsx がCookieを読む場合、その配下のログイン後ページは動的になります。
cookies()、headers()、または searchParams を使う
fetchのcache / revalidateオプション(no-store、revalidate: 0)を指定する
サーバー/クライアントコンポーネントの区別と、ページが静的/動的かどうかは別の話です。
区別 | 決まること |
|---|---|
サーバー/クライアントコンポーネント('use client') | コードをどこで実行するか |
静的/動的 | HTMLをいつ作るか(ビルド時/リクエストごと) |
サーバーコンポーネントでも静的ページになり、ビルド時に一度だけ実行されることがあります。
'use client' のコンポーネントでも、最初のHTMLはビルド時に作られます。
cookies() や connection() はサーバー側の機能なので、page.tsx などのサーバーコンポーネントで使います。
書き方 | fetchの結果 | ページ |
|---|---|---|
オプションなし | 結果はキャッシュしない | 静的のまま。ビルド時にfetchして、その結果を含むHTMLを作る |
| キャッシュしない | 動的 |
| キャッシュする | 静的 |
| 60秒ごとに更新 | 静的(ISR) |
| キャッシュしない | 動的 |
「Next.js 15からfetchの結果はキャッシュされない」という説明は、fetchの結果についてです。ページ自体は静的のままになる場合があります。指定できるのは no-store です。
connection() は next/server から読み込み、ページ内で await connection() と呼びます。戻り値はありません。
import { connection } from 'next/server';
await connection();これは「このページをビルド時ではなく、リクエストごとに生成する」という宣言です。
fetchを使わないページをSSGにしない場合にも使えます。
connection() 自体はキャッシュを操作しません。ページを動的にすることでNext.jsが private, no-store を付ける結果、ページの応答が共有キャッシュに保存されなくなります。fetchの結果をキャッシュしない no-store とは役割が異なります。
connection() はNext.js 15で安定版となり、unstable_noStore の後継です。同様に動的ページにする方法として、export const dynamic = 'force-dynamic' や、値を使わずに await cookies() を呼ぶ方法もあります。
どんな時にどこにキャッシュされるか、キャッシュされたくなかったらどうしたら良いかが改めて整理できて良かったです。
要約
コメント
まだコメントはありません。