Next.js App Routerってなに?初心者が導入してみて分かったこと【導入〜使い方】
記事を書いた背景
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.tsxとlayout.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 では、ページやレイアウトが非同期処理(例えば fetch や suspense を使ったデータ取得)を行う場合に、ローディング中の表示をカスタマイズするためのファイルとして loading.tsx を使うことができます。
// app/dashboard/loading.tsx
export default function Loading() {
return <p>読み込み中です...</p>;
}
特徴:
- そのディレクトリ直下の
page.tsxやlayout.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
末尾の「参考リンク」のリンクが切れてますよ
ありがとうございます!差し替えさせていただきました。
おかしいと思って確認してみましたが、当記事の「その他の補助ファイル」の中に書かれている
という規約は、実在しません。
間違いなら恐縮ですが、生成 AI のハルシネーションっぽい感じがします。裏取りはされましたか?