Next.js App Router 基礎

モダンなWeb開発のデファクトスタンダードであるNext.js App Routerのレンダリングやデータフェッチ、キャッシュの仕組みを図解で学びます。

学習をスタートする

ロードマップ

1

Server Components と Client Components

Next.js App Router の最大の特徴は、Reactの最新機能である React Server Components (RSC) に完全対応している点です。 第1章では、サーバーとクライアントでコンポーネントがどのように役割分担をしているのか、そしてどのように画面が描画されるのかを図解で学びます。 1. 2つのコンポーネントの基本概念 Next.js App Router では、コンポーネントはデフォルトで Server Components(サーバーコンポーネント) になります。必要に応じて Client Components(クライアントコンポーネント) と明示的に指定して使い分けます。 特徴 Server Components (RSC) Client Components (RCC) デフォルト はい (App Router) いいえ ("use client" が必要) 実行場所 サーバー側のみ サーバー側(初期ビルド時)& クライアント側 JSバンドルサイズ 0 (ブラウザにJSが送信されない) ブラウザに送信される(容量が増える) 対話性・状態管理 不可 (useState, useEffect 等は使えない) 可能 (状態やイベントリスナーを使用) データ取得 データベースやAPIへ直接セキュアにアクセス可能 通常はAPI経由でアクセス 2. サーバーサイドレンダリングの流れ(図解) コンポーネントがブラウザに届き、画面が表示されるまでの仕組みです。 1. サーバー側: 全ての Server Components を実行し、ブラウザが即座に表示できる「初期HTML」と、Reactの状態を復元するためのデータ「RSC Payload」を生成します。 2. ブラウザ側: * まず、JavaScriptの読み込みを待たずにHTMLをパースし、高速に初期画面を表示します。 * その後、ダウンロードしたJavaScriptを実行し、静的なHTMLに対してイベントハンドラーなどを結合(ハイドレーション)して、ページを操作可能な状態にします。 3. "use client" の正しい理解(境界の引き方) Client Components を使う場合は、ファイルの最上部に "use client" ディレクティブを記述します。 注意すべきなのは、"use client" を記述したファイルとそのファイルからインポートされるすべての子コンポーネントが自動的に Client Components になる という点です。 推奨されるコンポーネント設計(境界の最小化) 不要なJavaScriptをブラウザに送らないよう、Client Components は「必要な部分だけ」に最小化するのがベストプラクティスです。 まとめ * Next.js App Router は、Server Components がデフォルト。余計なJSを削減し表示を高速化する。 * 対話性(状態管理、イベントハンドラー)やブラウザ専用APIが必要な部分だけ、最上部に "use client" を付けて Client Components にする。 * サーバーでプレビュー(HTML)を作成して高速に表示し、後からJavaScriptを結合(ハイドレーション)することで、表示速度と機能性を両立している。 次は、Next.jsでのデータの取得方法と、それをキャッシュして表示を極限まで高速化する仕組みについて学びましょう!

2

ルーティングとデータフェッチ・キャッシュ

Next.js App Router では、フォルダ構造がそのままルーティングになり、コンポーネントの中で非常にシンプルにデータをフェッチできます。さらに、ページの読み込み速度を最大化するために強力なキャッシュ機構が備わっています。 第2章では、App Router のルーティング構造、データ取得方法、そして複雑な「4つのキャッシュ」について図解で解説します。 1. App Router のルーティング構造 フォルダ名がURLパスになり、そのフォルダ内に配置する特別なファイル名によって役割が決まります。 * page.tsx: そのルートの固有UI(ページ本体)。 * layout.tsx: 複数のページで共有されるUI(ヘッダー、サイドバーなど)。再レンダリングされず状態が維持されます。 * loading.tsx: ページの読み込み中に表示されるローディングUI(自動的にReact Suspenseでラップされます)。 * error.tsx: エラー発生時に表示される代替UI。 2. Server Components でのデータフェッチ RSC(Server Components)では、コンポーネント自体を async 関数にすることで、useEffect や fetch を使ったフックなしで直接データを非同期で取得できます。 3. Next.jsの「4つのキャッシュ」と判定フロー(図解) Next.jsには、パフォーマンス向上とAPIへの負荷を減らすため、4つの独立したキャッシュシステムが存在します。 キャッシュの概要 キャッシュ名 対象 保存場所 目的 Request Memoization 同一リクエスト内の fetch 重複 サーバーメモリ 1回のリクエスト中で同じAPI呼び出しをまとめる Data Cache 異なるリクエスト間のAPIデータ サーバーのディスク/メモリ データベースやAPIのデータを保存して再利用する Full Route Cache ページ全体のHTMLとRSC Payload サーバーのディスク ビルド時や初回アクセス時に静的にページを丸ごと生成する Router Cache 画面遷移時のページデータ ブラウザメモリ ユーザーが画面遷移する際の待ち時間をゼロにする データ取得とキャッシュ判定フロー キャッシュの制御方法 Next.js 15以降では、fetch のデフォルトの挙動はキャッシュしない(no-store)仕様へと変更されました。そのため、データをキャッシュして再利用したい場合は、明示的にオプションを指定する必要があります。 まとめ * App Router はフォルダ名がルーティングになり、layout.tsx や page.tsx を組み合わせてページを組み立てる。 * Server Components では async/await を用いて、サーバー上で直接かつ安全にデータを取得可能。 * Next.jsの 4つのキャッシュ は、ブラウザ(Router Cache)からサーバーのAPI取得(Data Cache)まで細かく連携し、高速化とサーバー負荷の軽減に貢献している。

3

ルーティングとレイアウト(Layouts & Templates)

Next.js App Routerでは、ファイルシステムをベースとした直感的なルーティングと、状態を維持できる入れ子(ネスト)状のレイアウトシステムが採用されています。 第3章では、フォルダー構成がどのようにページURLに対応するのか、そして画面全体を効率的に構成するためのレイアウトやテンプレート、ルートグループの仕組みを図解で解説します。 1. ファイルシステムベースのルーティング App Routerでは、app ディレクトリ内のフォルダー構造がそのままURLパスになります。 ページとして公開するルートには、必ずフォルダー内に page.tsx(または .jsx)を配置する必要があります。 * 動的ルーティング ([slug]): フォルダー名をブラケットで囲む(例: [id] や [slug])ことで、動的なURLパラメータ(例: /blog/nextjs-routing)を受け取るページを作成できます。 2. レイアウト(Layout)とテンプレート(Template) 画面を構築する際、ヘッダーやサイドナビゲーションなどの「共通UI」を定義するために layout.tsx と template.tsx を使用します。 レイアウト(Layout)の特徴 * 状態の維持 (State Preservation): ユーザーが子ルート間で遷移しても、レイアウトは再レンダリングされず、レイアウト内の状態(入力フォームの値やスクロール位置など)が維持されます。 * DOMの再作成なし: 遷移時にレイアウト部分のHTML要素は破棄されず、効率的に再利用されます。 テンプレート(Template)の特徴 * 毎回リセットされる: レイアウトと似ていますが、ルート遷移するたびにテンプレート内のインスタンスが新しく作成され、状態はリセットされます。 * ユースケース: ページ遷移ごとのフェードインアニメーションや、アクセス解析のページビュー計測(useEffect の再実行)を行いたい場合に適しています。 3. ルートグループ(Route Groups) 「URLのパス名には影響を与えたくないが、特定のページ群だけに共通のレイアウトを適用したい」または「ファイルを論理的なグループで整理したい」という場合には、ルートグループ を使用します。 フォルダー名を丸括弧で囲む(例: (marketing) や (dashboard))ことで、そのフォルダー名はURLのパスから除外されます。 具体例 以下のようにフォルダーを構成すると、URLは /login や /dashboard になりつつ、それぞれ異なるレイアウトを適用できます。 * app/(auth)/layout.tsx (認証画面用のシンプルなレイアウト) * app/(auth)/login/page.tsx → URLは /login * app/(main)/layout.tsx (ヘッダーやサイドナビ付きの標準レイアウト) * app/(main)/dashboard/page.tsx → URLは /dashboard 4. コードで見る Layout の基本構造 ルートレイアウト(app/layout.tsx)は、アプリケーションの最上位でHTMLタグやBodyタグを定義する必須のファイルです。 5. Next.js 15/16における重要な変更点:params の非同期化(Promise化) Next.js 15 以降、layout.tsx や page.tsx、route.tsx 等で受け取る params や searchParams の型が Promise に変更されました。 これにより、同期的にプロパティにアクセス(例: const slug = params.slug)しようとすると、開発モードで警告またはエラーが発生します。 正しい記述方法 (async / await の利用) まとめ * App Router はフォルダ名がルーティングになり、layout.tsx や page.tsx を組み合わせてページを組み立てる。 * Layout は状態を維持する共通のUI。Template は遷移するたびに状態がリセットされるUI。 * Next.js 15以降 では、params や searchParams は Promise となるため、await を使って非同期で取得する必要がある。 レイアウトをネスト(入れ子)にすることで、無駄な再レンダリングを防ぎながら、美しく一貫性のあるユーザーインターフェースを構築できます。次のステップでは、このルーティングと密接に関わるデータ取得(Data Fetching)の仕組みを学んでいきましょう!

4

Middleware によるルーティング・認証制御

Next.js App Router を用いたアプリケーション構築において、特定のルート(ダッシュボードやマイページなど)へのアクセスを制限する「認証ゲート(ログインチェック)」や、IP・地域制限を実装する際に欠かせないのが Middleware(ミドルウェア) です。本章では、Middleware の仕組みとセキュアな認証制御の設計について解説します。 1. Middleware とは? Next.js の Middleware は、リクエストがサーバーまたはエッジ(Vercelなど)に到達し、ページやAPIにルーティングされる 直前 に実行されるコードです。 役割と特徴 * 初期処理の共通化: リクエストのヘッダー書き換え、ログ出力、認証状態の検証などを一括で行えます。 * 高速なレスポンス: サーバーがHTMLやデータを生成する前に実行されるため、認証エラーによるリダイレクトを極めて高速に処理できます。 2. Middleware を介した認証フロー(図解) ログインしていないユーザーが、認証必須ページ(/dashboard)にアクセスした際のリクエストの流れを示します。 3. 実践的な Middleware のコード例 プロジェクトのルートディレクトリ(src/ 配下を使用している場合は src/middleware.ts)に配置します。 4. API や Server Actions での認証検証 Middleware によるチェックは「ページの遷移を防ぐ」ための一次防衛線であり、安全なAPIやデータ通信の担保には不十分 です。なぜなら、直接APIを叩くなどして悪意あるリクエストを送信することが可能なためです。 そのため、データを取得・書き換える Server Actions や Route Handlers の中では、必ず個別にセッションの検証を行い、二重に認証を強制する必要があります。 まとめ * Middleware はリクエストがページに届く前に動作し、認証やリダイレクトを制御する。 * NextResponse.redirect() で未認証ユーザーを瞬時にログイン画面へ流す。 * Middleware は一次防衛線であり、Server Actions や API の中でも二重の認証チェックが必須 である。

5

Server Actions と安全なデータ更新

Next.js App Router では、APIルート(/api/route.ts)を個別に定義することなく、サーバー上で実行される非同期関数をクライアントコンポーネントから直接呼び出す仕組みである 「Server Actions(サーバーアクション)」 が提供されています。 第5章では、Server Actions の仕組み、具体的な実装方法、および実務で必須となるセキュリティ・バリデーション設計について解説します。 1. Server Actions とは? Server Actions は、クライアントとサーバー間のシームレスなデータ更新を実現する仕組みです。 背後では、Next.js が自動的に HTTP POST リクエストの API エンドポイントを生成して通信をトンネリングします。 主なメリット * APIエンドポイント定義の不要化: データ更新ロジックをコンポーネントの近く、あるいは専用のサーバーモジュールに隠蔽できます。 * Progressive Enhancement(段階的エンハンスメント): JavaScript がブラウザでロードされる前、あるいは無効化されている状態でも、標準的な HTML フォーム送信として動作します。 * 型の安全性 (Type Safety): サーバー上の関数定義がそのままクライアント側で呼び出せるため、パラメータや戻り値の型が完全に保証されます。 2. Server Actions のデータフロー(図解) クライアントが Server Actions を実行し、データ更新後に画面が再検証(再描画)される流れは以下の通りです。 3. 基本的な実装例 サーバー側の Action 定義 ファイルまたは関数ブロックの先頭に "use server" ディレクティブを記述することで、そのコードがサーバーでのみ実行されることを明示します。 クライアント側のフォーム実装 4. セキュリティ・堅牢性設計のベストプラクティス Server Actions は、実質的にパブリックな API エンドポイントを公開することと同じです。そのため、セキュリティ上の対策が極めて重要です。 ① Zod による厳密なスキーマ検証 クライアントから送られてくる FormData やオブジェクトの値は、必ずサーバーサイドでスキーマ検証を行います。 ② 認証と認可の徹底 ユーザーの操作が許可されているか、セッション情報を確認してからデータベースにアクセスします。 まとめ * Server Actions は API エンドポイントを意識せず、サーバー側の関数をクライアントから透過的に呼び出せる機能。 * Progressive Enhancement に対応しており、JavaScript なしでも動作する頑強な UI/UX を提供可能。 * 実体は公開 API エンドポイントと同じであるため、Zod 等によるバリデーション と サーバー側での認証・認可 の実装が不可欠。 * データの更新後は、revalidatePath または revalidateTag を呼び出して、キャッシュを適切に更新する。