App Router による画面遷移の基本

はじめに
この節では、Next.js の App Router を使って、画面を分ける方法を学びます。
少し難しそうに見えるかもしれませんが、最初はとてもシンプルです。
考え方は、ほぼこれだけです。
フォルダを作ると、ページのURLになる
これがわかると、一気に見通しが良くなります。
この節では、次の4つを学びます。
appディレクトリで画面を分ける考え方page.tsxの役割Linkを使ったページ移動- 一覧から詳細へ移動する仕組み
1. この節のゴール
この節が終わるころには、次のことがわかる状態を目指します。
appフォルダの中でページを分けられるpage.tsxが何をするファイルかわかるLinkを使って画面を移動できる- 一覧から詳細へ進む仕組みがわかる 全部暗記しなくて大丈夫です。
まずは 「フォルダとURLがつながっている」 と理解できれば十分です。
2. 初期設定
まだプロジェクトを作っていない方は、ここから始めてください。
すでに作ってある場合は、確認だけで大丈夫です。
2-1. Node.js を確認する
ターミナルで次を入力します。
node -v
npm -v
数字が表示されればOKです。
2-2. Next.js アプリを作る
npx create-next-app@latest spot-share-app
質問が出たら、次のように選べば進めやすいです。
- TypeScript: Yes
- ESLint: Yes
- Tailwind CSS: Yes
src/directory: No- App Router: Yes
- Turbopack: Yes
- Import alias (
@/*): Yes 終わったら移動します。
cd spot-share-app
2-3. 開発サーバーを起動する
npm run dev
ブラウザで次を開きます。
http://localhost:3000
画面が出れば準備完了です。
3. app ディレクトリで画面を分ける考え方
Next.js の App Router では、app**** フォルダの中に画面を作ります。
たとえば、こんなフォルダ構成があるとします。
app
├─ page.tsx
├─ spots
│ └─ page.tsx
└─ spots
└─ [id]
└─ page.tsx
これが、次のURLとつながります。
/ → ホーム画面
/spots → スポット一覧画面
/spots/1 → スポット詳細画面
ここで大事なポイント
フォルダの場所が、そのままURLに近い形になる ということです。
つまり、
app/page.tsxはトップページapp/spots/page.tsxは/spotsapp/spots/[id]/page.tsxは/spots/1のような詳細ページ になります。
なぜこの考え方が大事か
最初にこのルールを知っておくと、
「この画面はどこに作ればいいの?」で迷いにくくなります。
たとえば、
- 一覧画面を作りたい
→
app/spots/page.tsx - 投稿画面を作りたい
→
app/spots/new/page.tsx - 詳細画面を作りたい
→
app/spots/[id]/page.tsxこのように考えられます。
4. page.tsx の役割
次に大事なのが page.tsx です。
page.tsx** は何をするファイルか**
これは、そのフォルダの ページ本体 を書くファイルです。
たとえば、ホーム画面ならこうです。
app/page.tsx
export default function HomePage(): JSX.Element {
return (
<main>
<h1>Spot Share</h1>
<p>おすすめスポットをみんなで共有しよう!</p>
</main>
);
}
このファイルがあると、/ にアクセスしたときにその内容が表示されます。
page.tsx** をひとことで言うと**
そのURLで表示する画面の中身を書くファイル です。
これだけ覚えておけば、最初は十分です。
一覧画面ならどうなるか
たとえば、一覧画面を作るならこうです。
app/spots/page.tsx
export default function SpotsPage(): JSX.Element {
return (
<main>
<h1>スポット一覧</h1>
<p>みんなが投稿したスポットを見てみよう。</p>
</main>
);
}
すると、/spots にアクセスしたとき、この内容が表示されます。
5. Link を使ったページ移動
ページを作っただけでは、まだ移動できません。
移動するには Link を使います。
Link** とは**
Link は、別のページへ移動するための部品 です。
Next.js では、普通の <a> タグではなく、基本的に Link を使います。
まずは使い方を見る
import Link from 'next/link';
export default function HomePage(): JSX.Element {
return (
<main>
<h1>Spot Share</h1>
<Link href="/spots">スポット一覧を見る</Link>
</main>
);
}
これで、「スポット一覧を見る」を押すと /spots に移動します。
もう1つ例を見る
import Link from 'next/link';
export default function HomePage(): JSX.Element {
return (
<main>
<h1>Spot Share</h1>
<div>
<Link href="/spots">一覧を見る</Link>
</div>
<div>
<Link href="/spots/new">新しく投稿する</Link>
</div>
</main>
);
}
このように書くと、
- 一覧ページへ行く
- 投稿ページへ行く という2つの移動を作れます。
href** には何を書くのか**
href には、移動先のパス を書きます。
たとえば、
href="/spots"→ 一覧画面へhref="/spots/new"→ 新規投稿画面へ という意味です。
6. 一覧から詳細へ移動する仕組み
ここが、この節のいちばん大事なところです。
一覧画面では、たくさんのスポットが並びます。
その中から1件を押すと、そのスポットの詳細画面 に移動したいです。
このとき使うのが ID です。
ID とは
ID は、1件ずつを区別するための番号や文字列です。
たとえば、スポットが3件あったとします。
const spots = [
{ id: '1', name: '静かな図書館' },
{ id: '2', name: 'おしゃれカフェ' },
{ id: '3', name: '学食の穴場席' },
];
この id を使うと、どのスポットを開くか決められます。
一覧から詳細に移動するコード例
import Link from 'next/link';
type Spot = {
id: string;
name: string;
};
const spots: Spot[] = [
{ id: '1', name: '静かな図書館' },
{ id: '2', name: 'おしゃれカフェ' },
];
export default function SpotsPage(): JSX.Element {
return (
<main>
<h1>スポット一覧</h1>
{spots.map((spot) => {
return (
<div key={spot.id}>
<h2>{spot.name}</h2>
<Link href={`/spots/${spot.id}`}>詳細を見る</Link>
</div>
);
})}
</main>
);
}
これで、
静かな図書館→/spots/1おしゃれカフェ→/spots/2のように移動できます。
なぜ ${spot.id} を使うのか
一覧には複数のデータがあります。
それぞれ違う詳細ページへ行く必要があります。
なので、固定で /spots/1 と書くのではなく、
そのデータの id を使ってURLを作ります。
<Link href={`/spots/${spot.id}`}>詳細を見る</Link>
この1行で、どのカードを押したかに応じて移動先が変わる ようになります。
7. 動的ルートの考え方
一覧から詳細へ移動するためには、受け取る側のページも必要です。
それがこれです。
app/spots/[id]/page.tsx
type SpotDetailPageProps = {
params: {
id: string;
};
};
export default function SpotDetailPage({
params,
}: SpotDetailPageProps): JSX.Element {
return (
<main>
<h1>スポット詳細</h1>
<p>ID: {params.id}</p>
</main>
);
}
[id]** の意味**
[id] は、変わる値が入る場所 です。
たとえば、
/spots/1/spots/2/spots/3のように、最後の部分が変わります。
この変わる部分を受け取るために、フォルダ名を [id] にします。
これで何ができるか
たとえば /spots/2 に移動すると、
params.id
の中に "2" が入ります。
これを使えば、「どのスポットを表示するか」を決められます。
8. 最小構成で一度やってみよう
ここまでの内容を、いちばん小さい形で試してみます。
app/page.tsx
import Link from 'next/link';
export default function HomePage(): JSX.Element {
return (
<main>
<h1>Spot Share</h1>
<p>おすすめスポットを共有しよう</p>
<Link href="/spots">スポット一覧を見る</Link>
</main>
);
}
app/spots/page.tsx
import Link from 'next/link';
const spots = [
{ id: '1', name: '静かな図書館' },
{ id: '2', name: 'おしゃれカフェ' },
];
export default function SpotsPage(): JSX.Element {
return (
<main>
<h1>スポット一覧</h1>
{spots.map((spot) => {
return (
<div key={spot.id}>
<p>{spot.name}</p>
<Link href={`/spots/${spot.id}`}>詳細を見る</Link>
</div>
);
})}
</main>
);
}
app/spots/[id]/page.tsx
type SpotDetailPageProps = {
params: {
id: string;
};
};
export default function SpotDetailPage({
params,
}: SpotDetailPageProps): JSX.Element {
return (
<main>
<h1>スポット詳細ページ</h1>
<p>選んだスポットのIDは {params.id} です。</p>
</main>
);
}
これだけで、
- トップ
- 一覧
- 詳細 の基本的な流れが作れます。
9. よくあるつまずき
1. page.tsx の場所を間違える
app/spots.tsx ではありません。app/spots/page.tsx です。
2. Link を import し忘れる
Link を使うときは、必ず上にこれを書きます。
import Link from 'next/link';
3. [id] を普通のフォルダ名にしてしまう
詳細ページは id ではなく、[id] にします。
4. href のパスが合っていない
フォルダ構成と href の中身が一致しているか確認しましょう。
10. ここまでのまとめ
この節でいちばん大事なのは、次の4つです。
appフォルダの中で画面を分けるpage.tsxがページ本体になるLinkで画面を移動できる- 一覧から詳細へは
idを使って移動する ひとことで言うと、こうです。
フォルダでページを作り、Link でつなぐ
この考え方がわかれば、Next.js の画面遷移の土台はかなり見えてきます。
練習問題
問題1
/spots のページを作るには、どこに page.tsx を置けばよいですか。
問題2
Next.js で別ページに移動するとき、基本的に使うものは何ですか。
問題3
一覧から詳細へ移動するとき、URLを変えるために使うものは何ですか。
回答
問題1の回答
app/spots/page.tsx です。
問題2の回答
Link です。
問題3の回答
id です。/spots/1 のように、スポットごとのIDをURLに入れて使います。
次に進む前のチェック
次へ進む前に、次の3つを確認してください。
app/page.tsxがトップページになるとわかるLinkでページ移動できるとわかる- 一覧から詳細へは
idを使うとわかる
ここまで理解できていれば十分です。
次は、URL設計とルーティングの考え方をさらに整理していけます。
