Next.js

React ベースのフルスタックフレームワークで、SSR、SSG、API Routes を統合的に提供する

フロントエンドReact
Next.js」の技術書を見る →

Next.js とは

Next.js は、Vercel が開発する React ベースのフルスタック Web フレームワークである。SSR (サーバーサイドレンダリング)、SSG (静的サイト生成)、ISR (増分静的再生成)、App Router、React Server Components を統合的に提供する。2016 年 10 月に公開され、2026 年 8 月時点の最新安定版は 16 系 (16.3.1) である。React の公式ドキュメントは、フルスタックの React アプリを作る際の選択肢として App Router 版の Next.js を挙げている (React Router や Expo と並ぶ選択肢の 1 つで、保守は Vercel)。

レンダリング戦略

Next.js の設計判断は「HTML をいつ作るか」の 1 点に集約される。ビルド時にまとめて作るか、リクエストのたびに作るか、作り置きを裏で差し替えるか、ブラウザに作らせるか。この選択はアプリ単位ではなくルート単位で決まるため、1 つのアプリの中に複数が同居する。

戦略タイミング用途
SSG (Static Site Generation)ビルド時ブログ、ドキュメント、LP
SSR (Server-Side Rendering)リクエスト時ダッシュボード、検索結果
ISR (Incremental Static Regeneration)バックグラウンドで再生成EC サイト、ニュース
CSR (Client-Side Rendering)ブラウザで実行インタラクティブな UI

落とし穴は「静的なつもりのページがリクエスト時レンダリングに倒れる」ことだ。従来のモデルでは、ルートの中で cookie・ヘッダー・検索パラメーターのようなリクエスト固有の値を読むと、そのルート全体が作り置きの対象から外れる。16 系で cacheComponents: true を有効にすると挙動が変わり、Suspense 境界の内側でそれらを読む限りルート全体を動的にせず、静的な外枠を先に返して該当部分だけをリクエスト時に流し込める (2026 年 8 月時点)。どちらのモデルで動いているかを取り違えると、キャッシュの効き方の理解がまるごとずれる。

App Router (Next.js 13+)

App Router は Next.js 13 で導入されたルーティング方式で、ディレクトリ構造がそのまま URL になり、ファイル名 (page / layout / route) が役割を表す。旧来の Pages Router を即座に捨てさせる仕組みではなく、apppages は同じアプリの中で同時に動くよう意図して設計されている。そのため既存アプリはルート単位で少しずつ移行できる。Pages Router の pages/api/* (API Routes) に相当するのは、App Router では route.ts (Route Handler) である。

app/
├── layout.tsx          # 共通レイアウト
├── page.tsx            # / ルート
├── about/
│   └── page.tsx        # /about ルート
├── blog/
│   ├── page.tsx        # /blog ルート
│   └── [slug]/
│       └── page.tsx    # /blog/:slug ルート (動的ルート)
└── api/
    └── users/
        └── route.ts    # Route Handler: /api/users

Server Components と Client Components

App Router では、コンポーネントは既定でサーバー側だけで実行される。ブラウザでの状態やイベントが必要な部分だけをファイル先頭の 'use client' で切り出す、という引き算の設計になる。

// Server Component (デフォルト): サーバーで実行、JS がクライアントに送られない
async function UserList() {
  const users = await db.users.findMany(); // サーバーで直接 DB アクセス
  return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
}

// Client Component: ブラウザで実行、インタラクティブ
'use client';
function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}

Server Components はサーバーで実行されるため、DB アクセスや API キーの使用が安全にできる。JavaScript がクライアントに送られないため、バンドルサイズが削減される。

描画の流れを追うと理解が固まる。サーバーは Server Components をレンダリングし、React ツリーの構造をコンパクトに表した中間データ (RSC ペイロード) を作る。Next.js はそのペイロードと Client Components のコードから HTML を組み立てて返し、ブラウザはまず HTML をそのまま表示する。その後で同じペイロードを使ってサーバー側とクライアント側のツリーを突き合わせ、JavaScript でハイドレートしてインタラクティブにする。以降の画面遷移では HTML ではなくペイロードだけを取りに行き、クライアント側で差分を当てる。

境界の解釈は間違えやすい。'use client' はファイル単位の宣言で、そのファイルが import するモジュールと、そこで直接レンダリングするコンポーネントに波及する。一方で children や props として渡された Server Component は、Client Component の中に置かれてもサーバー実行のままだ。この性質を使えば「インタラクティブな殻の中にサーバー専用の中身を差し込む」構成が書ける。ただし Client Component へ渡す props はシリアライズ可能でなければならず、関数をそのまま渡すことはできない。

静的エクスポート

サーバーを一切置かずに配信したい場合は、静的エクスポートを選ぶ。

// next.config.ts
const config: NextConfig = {
  output: 'export',  // 静的 HTML を生成 (S3 + CloudFront でホスティング)
};

output: 'export' で全ページを静的 HTML に出力すれば、S3 + CloudFront のような静的配信だけでホスティングできる。ただしサーバーを前提にした機能はまとめて使えなくなる。2026 年 8 月時点で静的エクスポートの対象外なのは、ISR、Server Actions、cookie やヘッダーの読み取り、rewrites・redirects・headers の設定、リクエストに依存する Route Handler、generateStaticParams() を持たない動的ルートなどだ。画像最適化も既定の loader では動かず、imagesloader: 'custom' と自前の loaderFile を指定して外部サービスへ委ねる形になる。安く済むのは「サーバーが要る機能を諦めた分だけ」であって、機能をそのまま維持して最安になるわけではない。

AWS でのホスティング

AWS に Next.js 専用の実行環境が用意されているわけではない。どの方式も「Node.js を動かす場所をどこにするか」の違いに帰着する。

方式特徴コスト
S3 + CloudFront (静的エクスポート)サーバーレス、最安ほぼ無料
CloudFront + Lambda@Edge + S3部品を自分で組む低〜中
ECS / Fargateフル機能中〜高
Amplify Hosting (compute)マネージド、CI/CD 統合、対応バージョンに制約低〜中

静的サイトなら S3 + CloudFront が最もコスト効率が良い。サーバー機能が必要なら、まず Amplify Hosting の compute で足りるかを確認する。ここで見落としやすいのが対応バージョンだ。Amplify Hosting のドキュメントが compute のサポート対象として挙げているのは 2026 年 8 月時点で Next.js 12 から 15 までで、16 系は載っていない。最新版に追随する前提なら、コンテナ (ECS / Fargate) で自前の Node.js 実行環境を持つか、16 系で入った Deployment Adapter API に対応した配置方式を検討することになる。CloudFront と Lambda@Edge を組み合わせる構成は公式に部品の対応表があるものの、そこには「これらは利用できる部品であって完成した統合ではない」と明記されている。マネージドの手軽さを期待して選ぶ対象ではない。

判断の順序は、①どのルートをリクエスト時に作る必要があるか ②サーバー機能を落として静的エクスポートで足りるか ③サーバーが必要ならどの実行環境がバージョン制約を満たすか、の 3 段になる。React や TypeScript の土台から体系的に押さえたい場合は、関連書籍もあわせて参照したい。

この記事は役に立ちましたか?

関連用語

関連する記事