NextjsのAppRouterで用いられるディレクトリ名、ファイル名についておさらいする

App Routerではフォルダ名やファイル名に基づいてアプリケーションのナビゲーションなどの挙動を設定します。この記事ではそんなフォルダ名やファイル名についてパターンを一覧で見れるようにまとめました。

## ファイル
### ルーティングに関するファイル
#### page
マッピングされたページごとのUIを記述するファイルです。ページの主要な内容はここに記述されます。
#### layout
マッピングされたページとそれ以降のページに対するUIを記述するファイルです。
`app`は以下にある場合は`html`タグや`body`タグを用いて記述する必要があり、App Routerでは配置することが必須となっています。
#### template
`layout`に似たような動きをするファイルです。こちらのファイルは`app`に置くことは強制されていません。
`layout`と大きく異なる部分はナビゲーション毎の動作です。`template`ではナビゲーション毎にUIを作り直すので状態が初期化されてしまいます。ページ毎になんらかの動作を行うようにしてほしい場合は`template`を利用します。
#### default
マッピングされていないページに訪れたときに表示されるUIを記述します。並行ルートとの相性が良い機能となります。
#### loading
マッピング毎に設けられる`Suspense`境界で表示されるUIを記述するファイルです。

#### error
マッピング毎に設けられる`ErrorBoundary`境界で表示されるUIを記述するファイルです。

#### global-error
`app`全体のエラーを扱うファイルです。`app/layout`の内容すら置き換える内容を記述する必要があるので`html`要素や`body`要素を用いて記述する必要があります。

#### not-found
`notFound`関数がスローされたときやマッピングされていないページに訪れたときに表示されるUIを記述するファイルです。

#### route
マッピングされた場所でAPIを定義することができるファイルです。これまで紹介したファイルと一緒に置くことはできません。

#### ルーティングまとめ
これまで紹介したルーティングファイルは以下のような形で組み立てられます(routeとdefaultはここに記述されない)。
```tsx
<ErrorBoundary fallback={<GlobalError />}>
  <Layout>
    <Template>
      <ErrorBoundary fallback={<Error />}>
        <Suspense fallback={<Loading />}>
          <ErrorBoundary fallback={<NotFound />}>
            <Page />
          </ErrorBoundary>
        </Suspense>
      </ErrorBoundary>
    </Template>
  </Layout>
</ErrorBoundary>
```
### icon
`favicon`や`icon`、`apple-icon`は`app`ディレクトリに置くことでマッピングしたページの`head`に追加してくれます。
これらはコードを用いて生成することもできます。
### manifest.json
`manifest.json`や`manifest.webmanifest`を`app`は以下に置くことでアプリに関する情報を提供できます。
これらはコードを用いて生成することもできます。
### opengraph-image
`opengraph-image`や`twitter-image`を設定することができます。
これらはコードを用いて生成することもできます。
### robots.txt
`robots.txt`を設定することができます。
これらはコードを用いて生成することもできます。

### sitemap.xml
`sitemap.xml`を設定することができます。
これらはコードを用いて生成することもできます。

## フォルダ
### 通常
App Routerは`app`ディレクトリ内で配置されたディレクトリ構成をもとにルーティングを行います。
`app/blog`に置かれたファイルは`example.com/blog`で展開されます。`app/user/profile`だと`example.com/user/profile`です。

### 動的ルート
`example.com/accounts/123`や`example.com/accounts/987`のように動的にパスが変更されるページを表現するには`[]`で囲むことで作成できます。例で出したケースは`app/accounts/[id]`のように書きます。
このようなパスは`example.com/accounts/123/edit`のようなパスにはマッチしませんが、`app/accounts/[...id]`のように`...`を加えることで`app/accounts/:id`に後続する全てのルートに一致するようになります。これはキャッチオールセグメントと呼ばれます。
そして、大括弧を一個増やして`app/accounts/[[id]]`のように書くことで`example.com/accounts/987`だけではなく、`example.com/accounts`もマッチするようになります。この記法はキャッチオールセグメントと重ねて利用することもできます。
動的ルートがマッピングする先に通常のルーティングがマッピングされている場合は通常のマッピングが優先されることに注意してください。`app/accounts/password`でマッピングされている場合は`example.com/accounts/password`には`app/accounts/[id]`ではなく、`app/accounts/password`の内容が反映されます。

### ルートグループ
ルートグループは`()`を囲むことで利用できるマッピングに関する機能です。`app/(royal)/accounts`の内容は`example.com/accounts`にマッピングされます。
App Routerではレイアウトなどの情報をより上位のディレクトリから引き継いで表示されますが、途中で引き継ぐ内容を分割したいことがあります。`example.com/posts`や`example.com/about`より下のレベルと`example.com/accounts`より下のレベルで異なる内容を表示したいとします。それぞれのディレクトリにレイアウトなどの情報を書くだけでも良いですが、ルートグループを用いることで、`app/(public)/posts`や`app/(public)/about`、`app/(private)/accounts`のようにすることで`posts`と`about`の共通化をしつつも異なる設定を`accounts`に対して行うことができます。

### 並行ルート
並行ルートは`@`で始まる名前でディレクトリを作成することで利用できる機能です。`app/@hello`や`app/@world`のようにディレクトリを作成すると`app`配下にあるレイアウトでそれらを用いることが可能となります。
`app/@hello/accounts`のように内部でディレクトリを積み重ねこともできます。しかし、`app/accounts`と`app/@hello/accounts`ディレクトリにファイルを置いて`/accounts`にアクセスしても`app/@world/accounts`にUIが宣言されていないため404ページが表示されます(ただし、Nextjsのナビゲーション機能を用いて遷移した場合はその部分に直前まで表示していたUIを表示し続けます)。
`/accounts`に直接アクセスしたときであってもUIを表示させたい場合は`app/@world/accounts`にUIを宣言するか、`app/@world`に`default`ファイルを記述する必要があります。

### インターセプトルート
インターセプトルートは`(.)`や`(..)`、`(..)(..)`、`(...)`などから始まる名前でディレクトリを作成することで利用できる機能です。
例えば`app/accounts`、`app/blog`、`app/accounts/(..)blog`のようにマッピングされているときに、`example.com/accounts`から`example.com/blog`にアクセスしたときに`app/accounts`ではなく、`app/accounts/(..)blog`の内容が表示されるようになります。
規則は相対パスと同じような感じで`(.)`は同じレベルの内容をインターセプトします。`(..)`はひとつ上のレベルの内容をインターセプトします。`(..)(..)`はふたつ上のレベルの内容をインターセプトします。`(...)`は`app`配下の内容をインターセプトします。

### プライベートフォルダ
`_`から始まるディレクト名のことをプライベートフォルダと言います。App Routerの理から外れたファイルを設置できます。`_components`のようにがルーティングから除外したいが、`app`内におきたいようなファイルを置くのがおすすめです。