【Next.js 15入門①】プロジェクト作成とApp Routerの基本

## はじめに

本記事では、Next.js 15 を用いたプロジェクト作成からフォルダ構成、App Router の基本的な使い方までを解説します。

### 想定読者

- React の基礎知識をお持ちの方
- Next.js での開発を始めてみたい方

### 本記事の目標

1. Next.js 15 のプロジェクトを立ち上げる手順を理解する
2. `src/app`フォルダを基点とした基本的なフォルダ構成を把握する
3. App Router によるルーティング、レイアウトなどの仕組みを学ぶ

---

## 1. 開発環境

以下の環境で動作を確認しながら進めます。

- Node.js v20.11.1 以上
- npm v9.x 以上
- TypeScript Version 5.3.3

---

## 2. プロジェクトの作成

ターミナルで任意のディレクトリに移動し、次のコマンドを実行して Next.js 15 のプロジェクトを作成します。

```bash
npx create-next-app@^15
```

実行すると、いくつかの質問が対話形式で表示されます。それぞれの質問に対して、以下のように回答してください。

| 質問内容 | 推奨回答 | 説明 |
|:-----------|:------------|:------------|
| What is your project named? | 任意（例: my-next-app） | プロジェクト名を入力します。カレントディレクトリを使う場合は . を入力します。 |
| Would you like to use TypeScript? | Yes | 型安全な開発ができるため、TypeScriptの利用をおすすめします。 |
| Would you like to use ESLint? | Yes | コード品質を保つために、ESLint（コードリントツール）を有効にします。 |
| Would you like to use Tailwind CSS? | Yes | スタイリングを効率化するため、Tailwind CSSを使用することをおすすめします。 |
| Would you like your code inside a src/ directory? | Yes | ソースコードを src/ ディレクトリ以下にまとめることで、構成が整理されます。 |
| Would you like to use App Router (recommended)? | Yes | Next.js 15以降はApp Routerが標準のルーティングシステムとなるため、有効化します。 |
| Would you like to use Turbopack for next dev? | No または Yes | Turbopackは開発サーバーのパフォーマンスを向上させます。試してみたい場合はYesを選びますが、Noでも問題ありません。 |
| Would you like to customize the default import alias (@/*)? | No | デフォルトのエイリアス設定（@/）のままで問題ありません。必要に応じて後から変更できます。 |

このように進めることで、最新の推奨構成に沿ったNext.js 15プロジェクトを簡単に作成できます。

また、これらの設定をすべてスキップして一括指定したい場合は、以下のようなコマンドも利用できます。

```bash
npx create-next-app@^15 --typescript --eslint --tailwind --src-dir --app
```

---

## 3. 基本のフォルダ構成（`src/app`）

プロジェクト作成後、最初にフォルダ構成を確認します。

```bash
src/
└── app/
    ├── layout.tsx   # 共通レイアウト
    ├── page.tsx     # トップページ
    ├── about/       # /about ページ
    │   └── page.tsx
    └── contact/     # /contact ページ
        └── page.tsx
```

- `layout.tsx`：ヘッダーやフッターなど、全ページで共通する UI を定義します。
- `page.tsx`：各フォルダごとにトップレベルのページコンポーネントとして扱われます。
- フォルダ名がそのまま URL パスになります（例：`/about`、`/contact`）。

---

## 4. 開発サーバーの起動と本番ビルド

### 4.1 開発サーバーの起動

```bash
npm run dev
```

`http://localhost:3000`で開発中のサイトを確認できます。

### 4.2 本番ビルドと起動

```bash
npm run build
npm run start
```

`npm run build`で生成される`.next`フォルダをもとに、本番サーバーが立ち上がります。

---

## 5. App Router の基本

Next.js 15 の App Router では、ファイルシステムをもとに自動的にルーティングが設定されます。以下の機能を順に見ていきます。

### 5.1 ページとレイアウト

#### 5.1.1 ルートレイアウト（`layout.tsx`）

```tsx
// src/app/layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="ja">
      <body>
        <header>
          <h1>タイトル</h1>
        </header>
        {children}
        <footer>© 2025 hoge Company</footer>
      </body>
    </html>
  );
}
```

すべてのページで共通のヘッダー・フッターを表示できます。

#### 5.1.2 ページコンポーネント（`page.tsx`）

```tsx
// src/app/page.tsx
export default function HomePage() {
  return <p>Hello, Next.js 15!</p>;
}
```

URL ルートに対応したフォルダ直下の`page.tsx`がページとしてレンダリングされます。

### 5.2 動的ルーティング

フォルダ名を`[param]`の形式にすると、動的ルーティングを実現できます。

```bash
src/
└── app/
    └── blog/
        └── [id]/
            └── page.tsx
```

```tsx
// src/app/blog/[id]/page.tsx
type PageProps = { params: { id: string } };

export default async function BlogPostPage({ params }: PageProps) {
  const { id } = params;
  return <div>Blog ID: {id}</div>;
}
```

`/blog/10`にアクセスすると`id`が文字列`"10"`として取得できます。

### 5.3 ルーティンググループ

グループ化したいフォルダを`(group)`の形式で作成すると、URL には含まれずグループだけを論理的にまとめられます。

```bash
src/
└── app/
    └── (auth)/
        ├── login/
        │   └── page.tsx
        └── register/
            └── page.tsx
```

```tsx
// src/app/(auth)/login/page.tsx
export default function LoginPage() {
  return <p>ログインページ</p>;
}
```

`/login`、`/register`でそれぞれアクセスできます。

### 5.4 NotFound ページ

`app/not-found.tsx`を作成すると、存在しないパスで表示される 404 ページをカスタマイズできます。

```tsx
// src/app/not-found.tsx
export default function NotFound() {
  return <h2>このページは存在しません</h2>;
}
```

### 5.5 Loading ページ

`loading.tsx`を配置するとデータフェッチ中に表示されるローディング UI を定義できます。

```bash
src/
└── app/
    └── blog/
        ├── loading.tsx
        └── [id]/
            └── page.tsx
```

```tsx
// src/app/blog/loading.tsx
export default function Loading() {
  return <p>Loading...</p>;
}
```

### 5.6 Error ページ

`error.tsx`を置くと、データフェッチエラー時などの表示をカスタマイズできます。

```bash
src/
└── app/
    └── blog/
        └── [id]/
            ├── error.tsx
            └── page.tsx
```

```tsx
// src/app/blog/[id]/error.tsx
"use client";
export default function ErrorPage() {
  return <p>エラーが発生しました。</p>;
}
```

### 5.7 API ルート（Route Handlers）

`src/app/api/`配下に`route.ts`を置くと、サーバーサイドの API エンドポイントを作成できます。
開発初期のモックAPIとしても、実運用時のエンドポイントとしても使用されます。

```bash
src/
└── app/
    └── api/
        └── users/
            └── route.ts
```

```ts
// src/app/api/users/route.ts
import { NextResponse } from "next/server";

export async function GET() {
  return NextResponse.json([
    { id: 1, name: "yamada" },
    { id: 2, name: "tanaka" },
  ]);
}
```

### 5.8 メタデータ設定

各ページで`export const metadata`または`export async function generateMetadata`を使い、タイトルや description を設定できます。

```tsx
// src/app/blog/[id]/page.tsx
import { Metadata } from "next";

export async function generateMetadata({
  params,
}: {
  params: { id: string };
}): Promise<Metadata> {
  return { title: `記事ID: ${params.id}` };
}
```

### 5.9 ミドルウェア

`src/middleware.ts`を作成すると、リクエストが到達する前に実行される「事前処理」を定義することができます。
例えば、ログインしていないユーザーをログインページにリダイレクトしたり、リクエストのログを記録するなどの用途で使われます。

```bash
src/
├── app/
│   └── dashboard/
│       └── page.tsx
└── middleware.ts
```

```ts
// src/middleware.ts
import { NextResponse, NextRequest } from "next/server";

// ダミーの認証トークン（実際はCookieやヘッダーから取得）
const validTokens = ["token123", "token456"];

export function middleware(request: NextRequest) {
  // クッキーからトークンを取得（本来は署名付きCookieやJWTを使います）
  const token = request.cookies.get("auth-token")?.value;

  // トークンが無効な場合はログインページにリダイレクト
  if (!token || !validTokens.includes(token)) {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  // 認証済みの場合はリクエストをそのまま進める
  return NextResponse.next();
}

export const config = {
  matcher: ["/dashboard/:path*"], // /dashboard配下のページすべてに適用
};
```

上記の例では、`/dashboard`にアクセスすると`/login`にリダイレクトします。


---

## まとめ

本記事では、Next.js 15 を使ったプロジェクトの作成方法から、App Router を中心とした基本的なフォルダ構成やルーティング機能までを解説しました。
この記事を通じて、Next.js 15 を用いたモダンな Web アプリケーション開発の第一歩となれば幸いです。