Zenn
📻

Next.js App Routerってなに?初心者が導入してみて分かったこと【導入〜使い方】

に公開3

記事を書いた背景

NextJsを使ったサービス開発に従事することになった。
これまでもなんとなーくで使っていたがちゃんと勉強ログとして残そうと思い、書いてみています。
※ 間違っているところがあった場合、コメントいただけると嬉しいですm__m

📌 この記事でわかること

  • Next.js 13以降で登場した「App Router」の概要
  • Pages Routerとの違い
  • App Routerの導入方法
  • 実際に使ってみた感想とハマりポイント
  • 公式リファレンスまとめ

🚀 App Routerとは?

Next.js 13で新しく登場したルーティングの方法です。

これまでの pages/ ディレクトリによるルーティング(Pages Router)に代わって、app/ ディレクトリを使った柔軟な構成が可能になりました。

App Router is a new routing mechanism built on top of React Server Components.

📖 公式リファレンス


🔁 Pages Routerとの違い

項目 Pages Router App Router
ルーティング方式 pages/index.tsx app/page.tsx
レイアウト共有 _app.tsx, _document.tsx layout.tsx
データ取得 getServerSideProps など fetch, async function(Server Component)
動的ルーティング [slug].tsx [slug]/page.tsx
SSR/SSG 明示的(getStaticPropsなど) 暗黙的(fetchの使い方で制御)
React Server Components ❌非対応 ✅対応

🛠 App Routerを使う準備

1. Next.js 13以上をインストール

npx create-next-app@latest your-app-name

プロジェクト作成時に「App Routerを使うか?」と聞かれるので Yes を選択

既存プロジェクトで移行する場合は、pages/とapp/は併存可能ですが、app/ が優先されます。

2. ディレクトリ構成の基本

App Routerを導入すると、Next.jsのディレクトリ構成が従来の pages ベースから app ベース に変わります。このディレクトリ構造を理解することで、ページ遷移やレイアウトの概念がより明確になります。

appディレクトリとは?

Next.js 13から導入された app ディレクトリは、各ルートごとにページ・レイアウト・ローディング・エラーハンドリングなどの機能をフォルダベースで分割管理できるようになっています。

/app
  ├── layout.tsx       ← 全体の共通レイアウト
  ├── page.tsx         ← トップページ(/)
  └── about/
        ├── page.tsx   ← /about ページ
        └── layout.tsx ← /about 用レイアウト

ファイルの役割

App Router では、用途に応じた特定のファイル名を使って、ページの構成や状態を管理します。以下は主なファイルの役割一覧です。

ファイル名 役割・用途
page.tsx 各ルートのページコンポーネント。URL に直接対応するページ本体です。
layout.tsx ページの共通レイアウト。子ルートにも継承され、children を通じて描画します。
loading.tsx ページの読み込み中に表示されるプレースホルダー UI。非同期レンダリングに対応。
error.tsx 該当ルート内でエラーが発生したときに表示される UI。
not-found.tsx ページが見つからなかったときのカスタム 404 表示。
template.tsx layout.tsx と似ているが、状態を共有せずに毎回再レンダリングする用途向け。

💡 page.tsxlayout.tsx の組み合わせにより、柔軟なルーティングとコンポーネントの再利用が実現します。


layout.tsx の基本構造

layout.tsx は、特定のルート以下に共通する UI 構成を定義します。親レイアウトは子レイアウトやページに自動で継承されます。

// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="ja">
      <body>{children}</body>
    </html>
  );
}

ポイント:

  • <html> や <body> の要素もここで定義できるため、アプリ全体の構造をコントロールしやすい
  • children を通じて、下位のページやレイアウトをネストして描画できる
  • metadata.ts と組み合わせることで、各ページごとのタイトルやメタ情報も管理可能

💡 layout.tsx は SSR におけるベース HTML を構築する重要な役割を持っています。app/layout.tsx は全ページ共通、app/(auth)/layout.tsx のようにグループごとにも設置できます。

loading.tsx でローディング表示をカスタマイズ

App Router では、ページやレイアウトが非同期処理(例えば fetchsuspense を使ったデータ取得)を行う場合に、ローディング中の表示をカスタマイズするためのファイルとして loading.tsx を使うことができます。

// app/dashboard/loading.tsx
export default function Loading() {
  return <p>読み込み中です...</p>;
}

特徴:

  • そのディレクトリ直下の page.tsxlayout.tsx が非同期処理を含んでいる場合、自動的に loading.tsx が表示される
  • ページ遷移時やデータ取得中にスケルトン UI やスピナーを表示することで、UX を改善できる
  • loading.tsxサーバーコンポーネントでも OK'use client' は不要)

使用例: Skeleton コンポーネントの表示

// app/products/loading.tsx
export default function Loading() {
  return (
    <div>
      <h2>商品を読み込み中...</h2>
      <div className="skeleton skeleton-card" />
      <div className="skeleton skeleton-card" />
    </div>
  );
}

Skeleton UI を活用すれば、読み込みの間もレイアウトが崩れず、ユーザーの離脱を防げます。


error.tsx でエラーハンドリング

各ページやレイアウトで非同期処理に失敗した場合に、独自のエラー表示を行いたいときには error.tsx を設置します。

// app/dashboard/error.tsx
'use client';

import { useEffect } from 'react';

export default function Error({ error, reset }: { error: Error; reset: () => void }) {
  useEffect(() => {
    console.error(error);
  }, [error]);

  return (
    <div>
      <h2>エラーが発生しました</h2>
      <button onClick={() => reset()}>再試行</button>
    </div>
  );
}

特徴:

  • 'use client' を必ず付ける(クライアントコンポーネントとして動作)
  • error は発生したエラーオブジェクト、reset はエラー状態をリセットして再試行できる関数
  • try/catch をグローバルに管理できる感覚で使える

その他の補助ファイル

ファイル名 説明
not-found.tsx 指定されたルートが存在しない場合の 404 表示をカスタマイズする
template.tsx layout.tsx に似ているが、状態を共有せず、毎回新しい状態で描画される
metadata.ts そのルートに関連付けるメタ情報をオブジェクト形式で定義する(SEO向け)

参考リンク

Discussion

Honey32Honey32

末尾の「参考リンク」のリンクが切れてますよ

koffeeedkoffeeed

ありがとうございます!差し替えさせていただきました。

Honey32Honey32

おかしいと思って確認してみましたが、当記事の「その他の補助ファイル」の中に書かれている

metadata.ts そのルートに関連付けるメタ情報をオブジェクト形式で定義する(SEO向け)

という規約は、実在しません。

https://nextjs.org/docs/app/api-reference/file-conventions/metadata

間違いなら恐縮ですが、生成 AI のハルシネーションっぽい感じがします。裏取りはされましたか?

ログインするとコメントできます