3.
ページ
App Router の基本
App Router とは
App Router は、「フォルダ/ファイル = URL」をルールとしたダイナミックルーティングです。Next.js 13 から プロジェクト直下の app/
を基準に page.tsx
ファイルを配置します。
ルーティングの大原則
よくある構成例
app/
├── api/
│ └── route.tsx
├── layout.tsx
├── page.tsx
├── chat/
│ └── page.tsx
└── chat/
├── page.tsx
└── [slug]/
├── page.tsx
├── loading.tsx
└── error.tsx
基本ルーティング
項目 | 説明 | |
---|---|---|
フォルダ | app/chat/ |
/chat でアクセス |
ページ | page.tsx |
フォルダ内のページファイル |
共通レイアウト1 | layout.tsx |
HTMLの共通枠を利用 |
共通レイアウト2 | template.tsx |
ページ遷移ごとに状態リセットされるレイアウト |
ネスト(階層 URL) | app/blog/[slug]/page.tsx |
/blog/abc でアクセス |
動的パラメータ | [param] 、可変長は [...param] |
パラメーター取得 |
動的 & ネストルーティング
形式 | フォルダ名 | 例 URL | searchParams / params 値 |
---|---|---|---|
単一 | [id] |
/post/123 |
{ id: '123' } |
可変長 | [...slug] |
/docs/a/b/c |
{ slug: ['a','b','c'] } |
オプション | [[lang]] |
/en/blog or /blog |
{ lang?: string } |
ルートグループ & URL クリーン化
フォルダ名 (group)
を使うと「URLに影響しない」グルーピングが可能です。
ファイル | URL |
---|---|
app/(marketing)/landing/page.tsx |
/ |
app/(app)/landing/page.tsx |
/dashboard |
ページ固有の補助ファイル
ファイル | タイミング / 目的 |
---|---|
loading.tsx |
データ取得待ち中に表示 |
error.tsx |
例外捕捉してユーザフレンドリ表示 |
not-found.tsx |
notFound() 呼び出し時に表示 |
レイアウト
レイアウトとは
最新のNext.js では App Router
(app/ ディレクトリ) を使ったレイアウト機能が導入されています。このレイアウトは React Server Components (RSC)
をベースにしており、以前の pages/
ベースのルーティングとは異なる構造になっています。
レイアウトの特徴
- ルートごとのレイアウトが可能
layout.tsx
- レイアウトはデフォルトでサーバーコンポーネント
- レイアウトは
children
を使ってネスト可能 - 共有コンポーネント(ナビゲーションやフッター)を保持しつつ、ページだけ再レンダリング
レイアウトの配置
Next.jsのレイアウトファイルはデフォルトで app/layout.tsx
が用意されています。

- Next.js 12のレイアウトは「components/layout.js」
レイアウトの構造
Next.js 13の共通レイアウトは、Root Layout
とchildren
で構成し、各コンテンツページはpage.tsx
を配置して表示します。

RootLayout
RootLayoutはアプリ共通のレイアウトで、「app/layout.tsx」に配置します。
app/
├── layout.tsx
metadata
metadata は、HTMLのタイトルや説明などを設定する機能です。
app/layout.tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Next Chat',
description: 'This is chat app sample.',
}
CSS
「global.css」をimportし、サイト全体のスタイルが反映されています。
import './globals.css'
レイアウトコンポーネント
レイアウト名は「RootLayout」で、ファンクションコンポーネントになっています。引数childrenは、React.ReactNode型を指定しています。
app/layout.tsx
export default function RootLayout({ children, }: { children: React.ReactNode}) {
}
children
レイアウト内で各ページコンポーネントを表示するには、childrenを利用します。ReactベースのためJSXでコーディングします。
app/layout.tsx
export default function RootLayout({ children, }: { children: React.ReactNode}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
レイアウト修正
共通レイアウトファイル「app/layout.tsx」を修正します。
metadata
不要な部分を削除し、metadataのタイトルと説明文を修正します。
app/layout.tsx
import type { Metadata } from "next";
import "./globals.css";
// metaデータ変更
export const metadata: Metadata = {
title: "Next Chat",
description: "Generated by create next app",
};
JSX
レイアウトのHTML(JSX)を修正します。
app/layout.tsx
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="ja">
<body>
{children}
</body>
</html>
);
}
確認
ウィンドウタイトルが変更されたか確認してみましょう。
トップページ
ルートページ
サイトのルートページ app/page.tsx
を修正します。
app/page.tsx
export default function HomePage() {
return (
<main className="min-h-screen flex items-center justify-center bg-gradient-to-br from-sky-100 to-sky-400 p-6">
<div className="text-center space-y-6">
<h1 className="text-4xl md:text-6xl font-extrabold text-gray-800">
ようこそ、Next Chatへ!
</h1>
<p className="text-lg md:text-xl text-gray-600">
友達・チーム・AIとチャットしよう
</p>
<div className="space-x-4">
<a href="/login"
className="px-6 py-3 bg-sky-600 text-white rounded-xl shadow hover:bg-sky-700 transition">
ログイン
</a>
<a href="/register"
className="px-6 py-3 bg-white border border-sky-600 text-sky-600 rounded-xl hover:bg-sky-50 transition">
新規登録
</a>
</div>
</div>
</main>
);
}
