はじめに

Next.js の App Router は、ファイルシステムベースのルーティングを採用しています。このガイドでは、ルーティングの基本概念から実践的な使い方まで、段階的に学んでいきます。

ルーティングの基本概念

Route 定義とは

Next.js では、appディレクトリ内のフォルダ構造がそのまま URL パスになります。これを**ファイルシステムベースルーティング**と呼びます。
app/
├── page.tsx             # / (ホームページ)
├── about/
│   └── page.tsx         # /about
└── blog/
    ├── page.tsx         # /blog
    └── [slug]/
        └── page.tsx     # /blog/[slug]

ルーティングの用語解説

Next.js のルーティングを理解するために、重要な用語を図解と共に説明します:
app/                     # ルートディレクトリ
├── blog/               # /blog
│   ├── page.tsx       # /blog
│   └── [slug]/        # /blog/[slug]
│       └── page.tsx   # /blog/[slug]
└── about/             # /about
    └── page.tsx       # /about

例: URLが /blog/hello-world の場合
- Route: /blog/hello-world
- Segments: "", "blog", "hello-world" (3つのセグメント)
  • Tree(ツリー): アプリケーション全体のディレクトリ構造を木構造で表現したもの
    • appディレクトリが根(ルート)となり、各ディレクトリが枝分かれして階層を形成
    • ファイルシステムの階層構造そのものを指す
  • Subtree(サブツリー): ツリーの一部分を指す用語
    • 例:app/blog/以下のすべてのディレクトリとファイルは、blog のサブツリー
    • 特定のディレクトリを起点とした部分的な階層構造
  • Segment(セグメント): URL パスの各部分を指す用語です。URL を/で区切った際の、それぞれの部分がセグメントです
    • 例:/blog/hello-worldの場合、bloghello-worldがそれぞれセグメント
    • Next.js では、各セグメントは app ディレクトリ内のフォルダに対応します
  • Route(ルート): 複数のセグメントから構成される完全なパス
  • Root(ルート): ツリー構造の最上位 または 起点となるノード
    • Next.js ではappディレクトリがルート
    • すべてのルーティングはここを起点として定義される
    • 注意:「Route(経路)」と「Root(根)」は異なる概念
  • Root Segment(ルートセグメント): 最初の/部分
  • Leaf(リーフ): ツリー構造において、それ以上子を持たない最終ノード
    • ディレクトリ構造では、サブディレクトリを持たない最終的なディレクトリ
    • 例:app/blog/[slug]/は、その下にディレクトリがなければリーフ
  • Leaf Segment(リーフセグメント): URL パスの最終セグメント
    • 例:/blog/hello-worldの場合、hello-worldがリーフセグメント
  • Dynamic Segment(動的セグメント): 角括弧で囲まれたセグメント(例:[slug]
  • Path(パス): URL の完全な文字列

Page ファイルの役割

page.tsx とは

page.tsxは、そのディレクトリを Web ページとして表示可能にする特別なファイルです。例えば、app/about/page.tsxがあれば/aboutという URL でアクセスできますが、page.tsxファイルがないディレクトリは、URL としてアクセスできません。
// app/about/page.tsx
export default function AboutPage() {
  return (
    <div>
      <h1>About Us</h1>
      <p>私たちについてのページです</p>
    </div>
  );
}

page ファイルの基本ルール

  1. 必須要素: ルートを公開するにはpage.tsxまたはpage.jsが必要
  2. デフォルトエクスポート: React コンポーネントをデフォルトエクスポートする
  3. ファイル名: 必ずpageという名前にする(indexではない)

Dynamic Route(動的ルート)の実装

Dynamic Route とは

URL の一部を動的に扱うルーティング機能です。ブログ記事やユーザープロフィールなど、同じレイアウトで異なるコンテンツを表示する際に使用します。

基本的な使い方

フォルダ名を角括弧[]で囲むことで、Dynamic Route を作成できます。角括弧内の名前が、パラメータ名として使用されます:
// app/blog/[slug]/page.tsx
export default function BlogPost({ params }: { params: { slug: string } }) {
  return (
    <article>
      <h1>ブログ記事: {params.slug}</h1>
      <p>URLパラメータ: {params.slug}</p>
    </article>
  );
}

slug とは?

slug(スラッグ)は、URL に使用される人間が読みやすい識別子です。通常、記事のタイトルなどを以下のように変換したものを指します:
  • スペースをハイフンに置換
  • 小文字に統一
  • 特殊文字を除去
例:
  • 記事タイトル: “Next.js 入門ガイド 2025 年版”
  • slug: “nextjs-getting-started-2025”
  • 結果の URL: /blog/nextjs-getting-started-2025
[slug]は慣例的な名前ですが、[id][postId][name]など、任意の名前を使用できます。 アクセス例:
  • /blog/first-postparams.slug = "first-post"
  • /blog/hello-worldparams.slug = "hello-world"

複数の Dynamic Segments

複数の動的パラメータも使用できます:
// app/shop/[category]/[product]/page.tsx
export default function ProductPage({
  params,
}: {
  params: { category: string; product: string };
}) {
  return (
    <div>
      <h1>カテゴリー: {params.category}</h1>
      <h2>商品: {params.product}</h2>
    </div>
  );
}
アクセス例:/shop/electronics/laptop

Layout(レイアウト)の活用

Layout とは

layout.tsxは、複数のページで共有される UI を定義するファイルです。ネスト可能で、子ルートに自動的に適用されます。

基本的な Layout

// app/layout.tsx (ルートレイアウト)
import Link from "next/link";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="ja">
      <body>
        <header>
          <nav>
            <Link href="/">ホーム</Link>
            <Link href="/about">About</Link>
            <Link href="/blog">ブログ</Link>
          </nav>
        </header>
        <main>{children}</main>
        <footer2025 My Site</footer>
      </body>
    </html>
  );
}

ネストされた Layout

各ディレクトリに独自の Layout を配置できます:
// app/blog/layout.tsx
import Link from "next/link";

export default function BlogLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="blog-container">
      <aside>
        <h3>最近の記事</h3>
        <ul>
          <li>
            <Link href="/blog/post1">記事1</Link>
          </li>
          <li>
            <Link href="/blog/post2">記事2</Link>
          </li>
        </ul>
      </aside>
      <div className="blog-content">{children}</div>
    </div>
  );
}

children プロパティ

childrenは、現在のレイアウトの子要素(ページやネストされたレイアウト)を表します。これにより、レイアウトの継承が実現されます。

実践的な例:ブログサイトの構築

完全なブログサイトの構造例:
app/
├── layout.tsx           # ルートレイアウト
├── page.tsx            # /
├── about/
│   └── page.tsx        # /about
└── blog/
    ├── layout.tsx      # ブログ用レイアウト
    ├── page.tsx        # /blog
    └── [slug]/
        ├── page.tsx    # /blog/[slug]
        └── loading.tsx # ローディング状態
各ファイルの実装例:
// app/blog/page.tsx - ブログ一覧
import Link from "next/link";

export default function BlogList() {
  const posts = [
    { slug: "getting-started", title: "Next.js入門" },
    { slug: "routing-guide", title: "ルーティング解説" },
  ];

  return (
    <div>
      <h1>ブログ記事一覧</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.slug}>
            <Link href={`/blog/${post.slug}`}>{post.title}</Link>
          </li>
        ))}
      </ul>
    </div>
  );
}

まとめ

Next.js App Router のルーティングは、以下の特徴を持ちます:
  1. 直感的: ディレクトリ構造がそのまま URL 構造になる
  2. 柔軟性: Dynamic Route や Layout による高度な制御
  3. 保守性: ファイルベースなので構造が明確
  4. パフォーマンス: 自動的なコード分割と最適化

参考リンク

これらの概念を理解することで、スケーラブルな Next.js アプリケーションを構築できます。次のステップでは、データフェッチングやミドルウェアなど、より高度な機能を学んでいきましょう。