Next.js

Next.js 16 の App Router と Pages Router 徹底比較

ⓘ本ページはプロモーションが含まれています

スポンサードリンク

App Router と Pages Router の概要

Next.js(13.x 以降)では、App Router がデフォルトのルーティング方式として提供されており、従来の Pages Router とは設計思想が大きく異なります。本セクションでは、両者の基本的な違いと、実務でどちらを選択すべきかの指針を解説します。

App Router はサーバーコンポーネントを中心に据えた 「UI とデータ取得をディレクトリ構造だけで完結させる」 アプローチです。一方、Pages Router はページ単位でクライアント側のロジックを記述し、getStaticProps などの従来のデータ取得手法に依存します。以下では具体的な相違点を見ていきます。

ルーティングモデルの違い

App Router は app/ ディレクトリ配下に配置した page.tsx / layout.tsx が自動的に URL にマッピングされます。Pages Router は pages/ 配下のファイル名がそのままパスになる従来型です。

項目 App Router (app/) Pages Router (pages/)
ルート定義方式 ファイルシステムベース(ページ・レイアウトはディレクトリ階層で管理) 同様にファイルシステムベースだが、_app.js / _document.js が全体レイアウトを担う
デフォルトコンポーネント種別 Server Component(サーバー側で実行) Client Component(ブラウザで実行)
データ取得の主流手法 fetch / use() で直接サーバーサイドに記述 getStaticProps, getServerSideProps などの API を使用

コンポーネントのデフォルト挙動

App Router では Server Component が標準 とされ、クライアント側でだけ必要なロジックがある場合にのみ "use client" ディレクティブを付与します。Pages Router のページは基本的にクライアントコンポーネントとして扱われるため、サーバーサイド専用の API(例:fetch)は getStaticProps など経由で呼び出す必要があります。

データ取得と ISR の統合

App Router ではページやレイアウト内部で 非同期関数をそのまま使用 でき、next: { revalidate } オプションで Incremental Static Regeneration (ISR) を簡単に設定できます。Pages Router でも ISR は可能ですが、getStaticProps の中で revalidate を返す形になるため、記述がやや冗長になります。


プロジェクトの作成とディレクトリ構成

このセクションでは、最新の Next.js(13 以降)で App Router を利用したプロジェクトをゼロから作成する手順と、実務で役立つディレクトリ構成例を紹介します。

初期化手順

以下のコマンドで TypeScript 環境が有効な Next.js アプリケーションを生成し、そのまま App Router 用に整備します。create-next-app@latest が常に最新版を取得するポイントです。

生成されたプロジェクトはデフォルトで pages/ ディレクトリが含まれます。App Router を使用するためにこのフォルダを削除し、代わりに app/ ディレクトリを作成します。

推奨される app/ ディレクトリ構造

App Router では レイアウトは階層ごとに上書き可能 な点が大きな特徴です。以下は実務でよく採用される例です。

  • layout.tsx はそのディレクトリ以下すべてに適用され、子ディレクトリで再定義すると上書きされます。
  • page.tsx が実際の UI を担い、サーバーコンポーネントとしてデータ取得が可能です。

ファイルベースルーティングとレイアウト実装

この章では、具体的なコード例を通して App Router のページ作成・レイアウト定義・ネストレイアウトの書き方を学びます。サーバーコンポーネントがデフォルトであることに注意しながら、必要に応じてクライアント側ロジックを分離します。

基本的なページ実装例 (app/page.tsx)

トップページは app/page.tsx に配置します。サーバーコンポーネントなので、fetch を直接使用して外部 API からデータを取得し、そのまま描画できます。

ポイントは next: { revalidate } オプションで ISR を有効にしている点です。これによりビルド時だけでなく、リクエストごとに最新データが取得されます。

共有レイアウト (app/layout.tsx)

全ページで共通のヘッダー・フッターを提供する layout.tsx はサーバーコンポーネントとして実装します。metadata オブジェクトは自動的に <head> に注入されます。

ネストレイアウトで UI を分離する (app/dashboard/layout.tsx)

ダッシュボードのようにページごとに異なるサイドバーやナビゲーションが必要な場合は、子ディレクトリに layout.tsx を配置 します。親のレイアウトを継承しつつ、追加要素だけを書き加える形になります。

この layout.tsx が適用されるのは /dashboard/** 以下すべてです。ページ (app/dashboard/page.tsx) は自動的に上記レイアウトでラップされます。


コンポーネントの種類とデータ取得戦略

App Router では Server Component と Client Component の境界を明示的に管理 することがパフォーマンス最適化の鍵です。また、use() フックや ISR オプションの正しい使い方も重要です。

Server Component と Client Component の判定基準

判定項目 Server Component(デフォルト) Client Component
実行環境 Node.js(サーバー側) ブラウザ
データ取得 fetch / use() が直接使用可 useEffect などクライアント側 API 必要
React フック 不可useState, useEffect なし) 完全に利用可能
宣言方法 ファイル冒頭に何も書かない "use client" を先頭行に記述

実務上の指針:UI がデータ取得だけで完結する場合は Server Component に留め、インタラクティブなロジック(クリックハンドラ等)が必要な箇所だけ "use client" を付与します。

fetch と ISR の実装例

next: { revalidate } が公式に推奨される ISR 指定方法です。旧来の cache: "force-cache" は非推奨となりつつあるため、可能な限り上記形で統一してください。

use() フックの注意点

Next.js 13.4 以降、React の use(実験的)をサーバーコンポーネント内で利用できますが、以下の制約があります。

  1. Server Component 限定:クライアント側では使用できません。
  2. 非同期関数は必ずキャッシュ可能:内部で fetch を行う場合は next: { revalidate } 等のオプションを付与し、キャッシュ戦略を明示してください。
  3. 安定性は未保証:現在は「experimental」フラグ付き機能であり、将来的な API 変更があり得ます。プロダクション環境では必ずテストを行い、必要に応じて await を用いた従来の書き方にフォールバックできるようにしておくと安全です。

Suspense と lazy の組み合わせ(クライアントコンポーネント)

インタラクティブな UI 部分で 遅延ロード が必要な場合は、React.lazySuspense を併用します。以下はチャート描画を遅延させる例です。

"use client" が付与されたファイルだけがクライアント側にバンドルされ、サーバーコンポーネントのサイズ増大を防げます。


動的ルート・ミドルウェア・Route Handlers(API Routes)

App Router でも 動的セグメントEdge Middleware、そして従来の API Routes に相当する Route Handlers が利用可能です。ここでは実装例と注意点を示します。

動的ページ (app/products/[id]/page.tsx)

  • params.id が URL の動的部分に自動マッピングされます。
  • notFound() はサーバー側で 404 ページを表示させるユーティリティです。

Edge Middleware(認証チェックの例)

Middleware は Edge Runtime 上で実行でき、リクエストがページや API に到達する前に処理できます。以下はトークンベース認証を行うシンプルな例です。

matcher を設定することで、不要なリクエストへのミドルウェア実行を防ぎ、パフォーマンス向上が期待できます。

Route Handlers(App Router の API エンドポイント)

pages/api/ に代わる Route Handlersapp/api/ 配下に配置し、HTTP メソッドごとに関数をエクスポートします。以下は商品取得と削除の例です。

  • GET / POST / PUT / DELETE といったメソッドを関数名でエクスポートするだけで、Edge Functions として自動デプロイされます。
  • request オブジェクトは標準の Web API 互換なので、ヘッダーやボディへのアクセスがシンプルです。

SEO・パフォーマンス最適化と Vercel デプロイ

App Router が提供する metadata 機構を活用すれば、SEO 設定がコードベースに統合されます。また、画像最適化やコード分割のテクニックと併せて、Vercel へのデプロイ手順も合わせて解説します。

metadata による SEO 設定

ページ単位で export const metadata = { … } を記述すると、Next.js が自動的に <head> タグへ注入します。動的パラメータが必要な場合は関数形式でも構いません。

generateMetadata はページがリクエストされるたびに実行され、SSR 時点で正しい meta 情報が生成されます。

画像・コード分割によるパフォーマンス改善

項目 推奨手法
画像最適化 next/image の自動サイズ調整と lazy‑loading(デフォルト有効)。外部ホストの場合は loader をカスタマイズ。
大規模ライブラリ クライアント側でだけ必要な場合は dynamic import + Suspense で遅延ロード。例:import("./HeavyLib")
CSS 管理 グローバルは globals.css、コンポーネント単位は CSS Modules(Component.module.css)を使用し不要なスタイルのバンドルを防止。
データキャッシュ ISR (next: { revalidate }) と タグベース再生成(Next.js 13.4+)で細かなキャッシュ制御が可能。

Vercel へのデプロイ手順

  1. Vercel CLI のインストール

bash
npm i -g vercel

  1. Git リポジトリを作成しプッシュ(GitHub が推奨)

bash
git init
git add .
git commit -m "Initial Next.js App Router project"
git branch -M main
git remote add origin https://github.com/yourname/my-next-app.git
git push -u origin main

  1. Vercel にプロジェクトを作成

bash
vercel login # アカウントでログイン
vercel # ディレクトリ内で実行、指示に従って設定

  • フレームワーク検出は自動的に Next.js と判定されます。
  • ビルドコマンドは npm run build、デプロイ先はデフォルトのプレビュー環境です。

  • 環境変数を設定

Vercel ダッシュボード → 「Settings」→「Environment Variables」で NEXT_PUBLIC_API_KEY 等必要なキーを追加します。ProductionPreview の両方に同じ名前で設定すると、ローカルと同様に利用できます。

  1. デプロイ完了の確認

デプロイが成功するとプレビュー URL が表示されます。その URL を本番ドメイン(例:example.com)へ割り当てれば運用開始です。Vercel は Edge Functions と連携し、先述の Middleware や Route Handlers も自動的に最適化された形で提供します。


まとめ

  • App Router vs Pages Router
  • App Router は Server Component がデフォルトで、レイアウト・データ取得がディレクトリ構造だけで完結。
  • Pages Router は従来通りクライアントコンポーネント中心で、getStaticProps 系が必要。

  • プロジェクト作成

  • npx create-next-app@latest --tsapp/ ディレクトリに切り替えるだけで即座に App Router が有効化できる。

  • ルーティングとレイアウト

  • page.tsx がページ本体、layout.tsx が階層ごとの共通レイアウト、子ディレクトリの layout.tsx で UI を細分化可能。

  • コンポーネントとデータ取得

  • Server Component と Client Component の境界を意識し、fetch(..., { next: { revalidate } }) で ISR を導入。
    use() は実験的機能なので安定版へのフォールバックも考慮。

  • 動的ルート・ミドルウェア・Route Handlers

  • [id]/page.tsx による動的ページ、Edge Middleware で認証、app/api/…/route.ts が API エンドポイントとして機能。

  • SEO・パフォーマンスとデプロイ

  • metadata / generateMetadata で SEO をコードベースに統合。
  • next/image と動的インポートで最適化し、Vercel にシームレスにデプロイできる。

以上のポイントを押さえておけば、Next.js(13 以降)の App Router を実務レベルで安全かつ効率的に活用できます。公式ドキュメントは随時更新されますので、最新情報は https://nextjs.org/docs/app を定期的に確認してください。

スポンサードリンク

-Next.js