ルーティングとページ — App Routerのファイルベースルーティング入門
Webアプリには必ず「URLと画面の対応づけ」=ルーティングが必要です。Next.js(App Router)の最大の特徴は、この対応づけを設定ファイルではなくフォルダとファイルの配置だけで表現できることです。
この章では、app/ 配下のディレクトリ構成がそのままURLになる仕組みと、<Link> による画面遷移までを押さえます。
学習者ルーティングって、ライブラリを入れて設定ファイルに書くものだと思ってた。フォルダを作るだけでURLになるの…?
ファイルベースルーティングの仕組み
App Routerでは、app/ ディレクトリの中の**フォルダがURLの区切り(セグメント)**になり、そのフォルダに置いた page.tsx がそのURLで表示される画面になります。
src/app/
├── page.tsx → / (トップページ)
├── about/
│ └── page.tsx → /about
└── blog/
└── page.tsx → /blog
つまり「/about というページを作りたい」なら、app/about/page.tsx を作るだけです。
// src/app/about/page.tsx
export default function AboutPage() {
return <h1>このサイトについて</h1>;
}
先生フォルダ名=URL、page.tsx=そのURLの中身。この2つの対応さえ掴めば、ルーティングの8割は理解したも同然だよ。

階層(ネスト)もフォルダで表現
フォルダを入れ子にすれば、URLも階層になります。
app/
└── blog/
├── page.tsx → /blog
└── settings/
└── page.tsx → /blog/settings
URLにならないフォルダ — page.tsx の有無がカギ
重要なルールがあります。page.tsx を置いたフォルダだけが、アクセス可能なURLになります。page.tsx のないフォルダは、URLの一部にはなっても単体ではアクセスできません(コンポーネントやユーティリティを置く置き場として使えます)。
app/
└── dashboard/
├── page.tsx → /dashboard(アクセス可能)
├── DashboardChart.tsx ← page.tsxではないのでURLにならない(部品置き場)
└── settings/
└── page.tsx → /dashboard/settings(アクセス可能)
特別な意味を持つファイル名
App Routerでは、いくつかのファイル名が予約されており、それぞれ決まった役割を持ちます。本書で扱う主要なものをまとめます。
| ファイル | 役割 | 解説する章 |
|---|---|---|
page.tsx | そのURLで表示される画面 | 本章 |
layout.tsx | 配下のページで共有される枠 | 第5章 |
loading.tsx | 読み込み中に表示するUI | 第8章 |
error.tsx | エラー発生時に表示するUI | 第8章 |
not-found.tsx | 404のときに表示するUI | 第8章 |
route.ts | APIエンドポイント(画面ではなくデータ) | — |
ページ間を移動する — Link コンポーネント
ページ間の遷移には、next/link の <Link> を使います。HTMLの <a> タグの代わりに使うことで、ページ全体を再読み込みせずに高速に画面を切り替えられます(クライアントサイドナビゲーション)。
import Link from "next/link";
export default function Nav() {
return (
<nav>
<Link href="/">ホーム</Link>
<Link href="/about">このサイトについて</Link>
<Link href="/blog">ブログ</Link>
</nav>
);
}主な props:
| prop | 型 | 説明 |
|---|---|---|
href | string(必須) | 遷移先のパス(/about など) |
prefetch | boolean | リンクを画面内に表示した時点で遷移先を先読みするか(既定で有効) |
replace | boolean | 履歴を「追加」せず「置き換え」る(戻るボタンの挙動が変わる) |
scroll | boolean | 遷移後にページ先頭へスクロールするか(既定 true) |
現在のページを判定する — usePathname
ナビゲーションで「今いるページ」を強調表示したいときは、usePathname で現在のパスを取得します。フックなのでClient Component("use client")で使います。
"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
export default function NavLink({ href, children }: { href: string; children: React.ReactNode }) {
const pathname = usePathname();
const isActive = pathname === href;
return (
<Link href={href} className={isActive ? "font-bold text-blue-600" : "text-gray-600"}>
{children}
</Link>
);
}
学習者usePathname はなんで "use client" が要るの?
usePathname は「今ブラウザがどのURLにいるか」を読むフックで、ブラウザ側でしか動きません。フック全般がそうであるように、Client Componentでのみ使えます。この区別は第3章で扱った Server/Client の考え方そのものです。
コードから遷移する — useRouter
ボタンのクリックや処理完了後にプログラムから遷移したいときは、useRouter を使います(こちらもClient Component専用)。
"use client";
import { useRouter } from "next/navigation";
export default function LoginButton() {
const router = useRouter();
async function handleLogin() {
await login();
router.push("/dashboard"); // ログイン後にダッシュボードへ
}
return <button onClick={handleLogin}>ログイン</button>;
}router.push(path) で遷移、router.replace(path) で履歴を置き換えて遷移、router.back() で戻る、といった操作ができます。
まとめ
- App Routerはフォルダ=URL、
page.tsx=その画面というファイルベースルーティング page.tsxを置いたフォルダだけがアクセス可能なURLになるlayout.tsx/loading.tsx/error.tsxなどのファイル名は予約されており、決まった役割を持つ- 内部リンクは
<Link>(高速遷移+先読み)。<a>は外部リンク用 - 現在地の判定は
usePathname、コードからの遷移はuseRouter(どちらもClient Component)
次の章では、複数のページで共通のヘッダーやサイドバーを表示する レイアウトと共通UI を扱います。layout.tsx の役割を理解すると、サイト全体の骨組みが作れるようになります。