TS-Tech
Next.js

App Router の特殊ファイルを理解する

6
  • ルーティング

App Router の特殊ファイルを理解する — Next.js Tips

App Router では、フォルダ名が URL になるだけではありません。ファイル名そのものが役割 になります。page.tsxlayout.tsx はすでに触った前提で、残りを地図として置いておきます。

全部を最初から覚える必要はありません。名前を見て「あ、あれか」と戻ってこられれば十分です。

参考: Next.js — Project structure · Next.js — File conventions


目次

  1. なぜ特殊ファイルがあるか
  2. よく使うファイル
  3. あとでよいファイル
  4. 画面と共通枠
  5. 読み込み・エラー・404
  6. API と middleware
  7. 同居できない組み合わせ
  8. よくある勘違い

なぜ特殊ファイルがあるか

Pages Router だと _app.tsx や自前コンポーネントで共通処理を組み立てがちでした。App Router では、次のようなことを 決まったファイル名 で宣言します。

  • 画面 → page.tsx
  • 共通枠 → layout.tsx
  • 読み込み中 → loading.tsx
  • エラー → error.tsx

覚える名前は増えますが、「どこに何を置くか」がプロジェクト間で揃いやすいです。


よく使うファイル

いまの段階で意識するのは、だいたいこれだけです。

ファイル 役割 URL を作るか
page.tsx その URL の画面 する
layout.tsx 下のページを共通枠で囲む しない
loading.tsx 読み込み中の UI しない
error.tsx その範囲のエラー UI(Client Component) しない
not-found.tsx 404 UI。notFound() からも表示 しない
route.ts HTTP API(Route Handler) する(例: /api/hello

要点はひとつです。page.tsx(または route.ts)があるフォルダだけがルートになる。

ブラウザで /blog/demo を開いたときのイメージです(全部のファイルが毎回出るわけではありません)。

flowchart TD  Req["リクエスト /blog/demo"] --> MW{"middleware.ts\nあれば先に実行"}  MW --> RL["app/layout.tsx\n全体の共通枠"]  RL --> BL["blog/layout.tsx\nブログ用の枠"]  BL --> LD{"blog/loading.tsx\n読み込み中なら表示"}  LD --> PG["blog/[slug]/page.tsx\n記事画面"]  PG --> OK["レスポンス"]  PG -.-> ER["途中で例外 → error.tsx"]  PG -.-> NF["notFound() → not-found.tsx"]

API(route.ts)のときは画面系の layout / page ではなく、対応する route.ts が応答します。


あとでよいファイル

一覧には載せておきますが、最初はスルーして大丈夫です。

ファイル ひとこと
template.tsx layout に似るが、遷移のたびに再マウント
default.tsx Parallel Routes(@slot)用。単一ルートではまだ出ない
global-error.tsx root layout ごと落ちたとき用。<html> / <body> が必要
forbidden.tsx / unauthorized.tsx 認可失敗 UI(設定が必要な場合あり)
middleware.ts リクエスト前の横断処理(src/ またはプロジェクトルート)
sitemap.ts / robots.ts / icon など SEO・アイコン用の特殊パス
instrumentation.ts サーバー起動時フック

画面と共通枠

page.tsx

その URL の本体です。src/app/about/page.tsx があれば /about が生えます。layout.tsx だけあっても URL はできません。

layout.tsx

そのフォルダより下にあるページを、共通の枠で囲みます。ヘッダーなどを 各ページにコピペするのではなく、枠の中にページがはまります。差し込み口が {children} です。

// イメージ<body>  <header>...</header>  {children}  {/* ← ここに / や /about、/blog/... が入る */}</body>

root の layout.tsx<html><body> を持ち、全体共通に向きます。blog/layout.tsx を足すと、外側の枠 → 内側の枠 → ページの順になります。

template.tsx(あとでよい)

見た目は layout に近いですが、遷移のたびに中身が作り直されます。アニメーションを毎回最初から始めたいとき向けです。普通の共通枠は layout.tsx で足ります。


読み込み・エラー・404

loading.tsx

その範囲の読み込み中 UI です。about/loading.tsx を置けば /about 用のスケルトンになります。中では Suspense 境界として働きます。

最短だとこんな感じです。

// src/app/blog/loading.tsxexport default function Loading() {  return <p>読み込み中…</p>;}

error.tsx

例外が起きたときの画面です。Client Component である必要があります(reset で再試行するため)。親の layout までは巻き戻しません。not-found.tsx(見つからない)とは別物です。

not-found.tsx

URL が無いときや、コードから notFound() を呼んだときに出ます。普段の 404 カスタムはここからです。global-error.tsx は root layout 自体が落ちたレアケース用なので、先に使うのは通常の error.tsx です。


API と middleware

route.ts

画面ではなく、GET / POST などの HTTP メソッドを export します。

// src/app/api/hello/route.ts → /api/helloexport async function GET() {  return Response.json({ message: "hello" });}

page.tsx と同じフォルダには置けません。API は api/ など別フォルダに分けます。

middleware.ts(あとでよい)

マッチしたリクエストの手前で動きます。ログインチェックやリダイレクト向きです。置き場所は src/app/ の中ではなく、src/middleware.ts かプロジェクトルートです。

Metadata 系(sitemap.ts / icon など)は、画面とは別ラインの特殊パスだと思えば大丈夫です。


同居できない組み合わせ

いちばんハマりやすいルールです。

組み合わせ 結果
同じフォルダに page.tsxroute.ts 不可。UI と API はフォルダを分ける
layout.tsx だけ URL はできない。page.tsx が別途必要
loading.tsx / error.tsx / not-found.tsxpage.tsx 。同じセグメントに並べてよい
# OKsrc/app/about/page.tsxsrc/app/about/loading.tsx# NGsrc/app/about/page.tsxsrc/app/about/route.ts   ← 同じフォルダはだめ# OK(API は別フォルダ)src/app/api/about/route.ts

よくある勘違い

思いがち 実際
layout.tsx を置けばページになる page.tsx が必要
error.tsxnot-found.tsx は同じ 例外 UI と 404 UI で別
全部 root に置けばよい セグメントごとに置ける。blog/loading.tsx/blog 以下向け
route.tspages/api と同じ場所感覚 App Router では app 配下のフォルダ+route.ts
特殊ファイルを全部最初から用意する 不要。必要になったときに足す

いまのプロジェクトでの位置づけ

ファイルベースルーティングで触ったのは、だいたい次です。

src/app/├── layout.tsx          ← 共通枠├── page.tsx            ← /├── about/page.tsx      ← /about└── blog/    ├── layout.tsx    └── [slug]/page.tsx

ここに例えば次を足すと、役割がはっきりします。

  • src/app/blog/loading.tsx … 記事読み込み中
  • src/app/not-found.tsx … 独自 404
  • src/app/api/hello/route.ts … JSON API

特殊ファイルは「全部覚える」より、一覧を見て必要なときに開く 使い方で十分です。

シェア