# 機能設計書 29-getStaticPaths

## 概要

本ドキュメントは、Next.js Pages RouterにおけるgetStaticPaths機能の設計を記述する。getStaticPathsは、動的ルートで静的生成（SSG）を行う際に、ビルド時に事前生成すべきパスを定義するAPIである。

### 本機能の処理概要

**業務上の目的・背景**：動的ルート（例：`/blog/[slug]`）で静的サイト生成を行うには、ビルド時にどのパスのページを生成するかを知る必要がある。getStaticPathsは、事前生成すべきパスの一覧と、定義されていないパスへのアクセス時の挙動（fallback）を定義する。これにより、動的コンテンツの静的配信を実現する。

**機能の利用シーン**：ブログ記事の全記事ページの事前生成、商品詳細ページの事前生成、カテゴリページの事前生成、ドキュメントサイトの全ページ生成など。

**主要な処理内容**：
1. ビルド時にgetStaticPaths関数を実行してパス一覧を取得
2. 戻り値のバリデーション（paths配列、fallbackオプション）
3. 各パスの正規化とルートパラメータの検証
4. i18n対応のパスロケール処理
5. fallback戦略（false/true/'blocking'）の適用

**関連システム・外部連携**：Pages Routerのビルドシステム、getStaticProps、動的ルート（Dynamic Routes）と連携する。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | getStaticPathsはビルド時の処理であり、直接的な画面はない |

## 機能種別

パス生成 / ビルド時処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| context.locales | string[] | No | サポートロケール一覧 | i18n有効時に提供 |
| context.defaultLocale | string | No | デフォルトロケール | i18n有効時に提供 |

### 入力データソース

- ビルド時のi18n設定情報
- 外部API/CMS/データベース（ユーザー実装部分でパス一覧を取得）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| paths | Array<string \| { params: Record<string, string>, locale?: string }> | 事前生成するパスの一覧 |
| fallback | boolean \| 'blocking' | 未定義パスへのアクセス時の挙動 |

### 出力先

- ビルドシステムの静的パス生成指示
- prerender-manifest.jsonへの記録

## 処理フロー

### 処理シーケンス

```
1. ルートパラメータ取得
   └─ getRouteRegexでルートのパラメータキーを抽出
2. getStaticPaths実行
   └─ ユーザー定義関数にlocales/defaultLocaleを渡して実行
3. 戻り値バリデーション
   └─ paths配列とfallbackの型チェック
4. パス正規化
   └─ 文字列パスの場合はルートマッチャーで検証、オブジェクトの場合はパラメータの網羅性チェック
5. i18n処理
   └─ ロケールの検出と正規化
6. 事前生成パス登録
   └─ 正規化されたパスをprenderRoutesとして記録
```

### フローチャート

```mermaid
flowchart TD
    A[ビルド開始] --> B["getRouteRegex(page) - パラメータキー取得"]
    B --> C["getStaticPaths({locales, defaultLocale})"]
    C --> D{戻り値バリデーション}
    D -->|paths未定義/不正| E[ビルドエラー]
    D -->|fallback未定義| F[ビルドエラー]
    D -->|OK| G[パス配列のループ処理]
    G --> H{パスの型}
    H -->|string| I[ルートマッチャーで検証]
    H -->|object| J[パラメータの網羅性チェック]
    I --> K[i18n正規化]
    J --> K
    K --> L[prerenderedRoutesに登録]
    L --> M{fallback設定}
    M -->|false| N[未定義パスは404]
    M -->|true| O[未定義パスはフォールバックHTML]
    M -->|blocking| P[未定義パスはSSR後にキャッシュ]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-29-01 | 動的ルート専用 | getStaticPathsは動的ルート（[param]を含むルート）でのみ使用可能 | 非動的ルートでは使用不可 |
| BR-29-02 | getStaticProps必須 | getStaticPathsはgetStaticPropsと組み合わせて使用する必要がある | getStaticProps未定義でgetStaticPathsは警告 |
| BR-29-03 | fallback必須 | fallbackプロパティは必ず返す必要がある（boolean または 'blocking'） | 常時 |
| BR-29-04 | パラメータ網羅性 | pathsのオブジェクト形式ではルートのすべてのパラメータを含む必要がある | オブジェクト形式のパス指定時 |
| BR-29-05 | パラメータ型制約 | パラメータ値は文字列でなければならない | オブジェクト形式のパス指定時 |
| BR-29-06 | fallback: false | 未定義パスへのアクセスは404を返す | fallback: false設定時 |
| BR-29-07 | fallback: true | 未定義パスはフォールバック版を先にレスポンスし、バックグラウンドでSSG生成 | fallback: true設定時 |
| BR-29-08 | fallback: 'blocking' | 未定義パスはSSRで生成し、以降はキャッシュから配信 | fallback: 'blocking'設定時 |

### 計算ロジック

パス文字列からのルートマッチング：`getRouteMatcher(getRouteRegex(page))`で動的パラメータを抽出し、返されたパスが有効なルートかを検証。

## データベース操作仕様

### 操作別データベース影響一覧

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 無効な戻り値 | getStaticPathsがオブジェクトを返さない | `{ paths: [], fallback: boolean }`形式を返す |
| - | 不正なキー | paths/fallback以外のキーが含まれる | 不要なキーを削除 |
| - | fallback未定義 | fallbackプロパティがない | fallbackを追加 |
| - | paths型エラー | pathsが配列でない | pathsを配列にする |
| - | パスマッチエラー | 文字列パスがルートにマッチしない | パスの形式を修正 |
| - | パラメータ不足 | オブジェクトパスに必要なパラメータがない | 全パラメータを含める |

### リトライ仕様

ビルド時のエラーのためリトライは不要。開発者がコードを修正してリビルドする。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- getStaticPathsはビルド時に1回のみ実行
- パス数が多い場合はビルド時間に影響（数千〜数万パスの場合は注意）
- fallback: true/'blocking'により、ビルド時間の最適化が可能

## セキュリティ考慮事項

- getStaticPaths内のコードはサーバーサイドのみで実行
- 返されるパス情報自体は公開情報（URLパスの一部）であるため、特別な保護は不要

## 備考

- App Routerでは`generateStaticParams`がgetStaticPathsの代替
- getStaticPathsはPages Router専用のAPI
- パス数が膨大な場合は`fallback: 'blocking'`でオンデマンド生成を推奨

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

getStaticPathsの型定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.ts | `packages/next/src/types.ts` | `GetStaticPaths`型、`GetStaticPathsContext`型、`GetStaticPathsResult`型 |

**読解のコツ**: `GetStaticPathsResult`の`paths`は文字列配列またはオブジェクト配列のunion型。`fallback`は`boolean | 'blocking'`。

#### Step 2: エントリーポイントを理解する

ビルド時のgetStaticPaths実行。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | pages.ts | `packages/next/src/build/static-paths/pages.ts` | `buildPagesStaticPaths()`関数がgetStaticPathsの実行とバリデーションを行う |

**主要処理フロー**:
1. **26-27行目**: `getRouteRegex`と`getRouteMatcher`の取得
2. **31-37行目**: getStaticPaths関数の実行
3. **43-51行目**: 戻り値がオブジェクトであることの検証
4. **53-63行目**: 不正なキーのチェック
5. **65-75行目**: fallbackプロパティの必須チェック
6. **86-100行目以降**: パス配列のバリデーションとi18n正規化

#### Step 3: render.tsxでの統合を理解する

レンダリングパイプラインでのgetStaticPaths関連チェック。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | render.tsx | `packages/next/src/server/render.tsx` | getStaticPathsの存在チェックと排他制約（583-601行目） |

### プログラム呼び出し階層図

```
next build [src/build/index.ts]
    |
    +-- buildPagesStaticPaths() [src/build/static-paths/pages.ts]
            |
            +-- getRouteRegex(page) - ルートパラメータキー抽出
            +-- getRouteMatcher() - パスマッチャー生成
            |
            +-- getStaticPaths({locales, defaultLocale}) ← ユーザー定義関数
            |
            +-- 戻り値バリデーション
            |       +-- オブジェクト型チェック
            |       +-- paths/fallbackキーチェック
            |       +-- fallback型チェック
            |
            +-- パス配列処理（ループ）
                    +-- 文字列パス: ルートマッチャーで検証
                    +-- オブジェクトパス: パラメータ網羅性チェック
                    +-- i18n正規化
                    +-- encodeParam
                    +-- prerenderedRoutesに登録
```

### データフロー図

```
[入力]                        [処理]                             [出力]

ルート定義              ──> getRouteRegex()                  ──> パラメータキー
/blog/[slug]                 |
                             |
{locales,              ──> getStaticPaths(context)           ──> {paths, fallback}
 defaultLocale}              |
                             |
paths配列              ──> バリデーション + 正規化            ──> PrerenderedRoute[]
                             |
PrerenderedRoute[]     ──> ビルドパイプライン                 ──> HTML + JSON生成
                             |
fallback設定           ──> prerender-manifest.json           ──> ランタイム設定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| pages.ts | `packages/next/src/build/static-paths/pages.ts` | ソース | getStaticPaths実行とバリデーション |
| types.ts | `packages/next/src/types.ts` | ソース | GetStaticPaths型定義 |
| render.tsx | `packages/next/src/server/render.tsx` | ソース | getStaticPathsの統合チェック |
| route-regex.ts | `packages/next/src/shared/lib/router/utils/route-regex.ts` | ソース | ルート正規表現生成 |
| route-matcher.ts | `packages/next/src/shared/lib/router/utils/route-matcher.ts` | ソース | ルートマッチング |
| utils.ts | `packages/next/src/build/static-paths/utils.ts` | ソース | パスエンコード等のユーティリティ |
| fallback.ts | `packages/next/src/lib/fallback.ts` | ソース | fallback解析（parseStaticPathsResult） |
| index.ts | `packages/next/src/build/index.ts` | ソース | ビルドプロセスでのgetStaticPaths呼び出し |
