Next.jsによるWebアプリケーション開発概論

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

3おすすめスポット共有アプリを作りながら学ぶ 画面遷移設計・状態管理・ユーザー入力処理
Next.jsTailwind CSSアプリ開発開発Web開発

はじめに

この節では、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/spots
  • app/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 にアクセスしたとき、この内容が表示されます。


ページを作っただけでは、まだ移動できません。

移動するには 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 です。

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設計とルーティングの考え方をさらに整理していけます。

教材トップへ戻る