O hirunewani blog

Tabs using Parallel Routes with Next.js App Router

Created at

公式ドキュメントを十分に読んでいないと理解が難しいと思われるParallel routesが404になる理由やdefault.jsの意味について、タブの実装を例に書いた。

次のようなディレクトリ構造を例にする。

app
├── layout.tsx
├── page.tsx
└── @tab
    ├── page.tsx
    └── new
        └── page.tsx

App Routerでは、@から始まるディレクトリのページを上位のlayout.tsxで受け取れる。

// app/layout.tsx
export default Layout({ children, tab }){
    return (
        <div>
            <nav>
                <Link href="/">Home Tab</Link>
                <Link href="/new">New Tab</Link>
            </nav>
            <div>
                {children}
                {tab}
            </div>
        </div>
    );
}

これだけで、パスに応じてtabが切り替わる。ただし、これだと/newsにアクセスした状態でリロードすると404が表示される。

Parallel Routesにリロード耐性を付ける

なぜ404が表示されるかというと、/newに対応するapp/new/page.tsxが存在しないからである。Parallel routesでは、1つでも対応していないルートが存在すると404になる。

app/default.tsxを配置することで、これを回避できる。 default.tsxは、ハードナビゲーション時に対応するルートがない場合のフォールバックを提供する。

https://nextjs.org/docs/app/api-reference/file-conventions/default

これは逆のパターンでも発生する。例えばapp/about/page.tsxが存在する場合、app/@tab/about/page.tsxが存在しないため、/aboutにアクセスすると404が表示される。この場合、app/@tab/default.tsxを配置することで回避できる。

Parallel Routesを扱うときはdefault.tsxが大事

つまり、次のようなディレクトリ構造にしておくことで、アプリが拡張されていく中で意図せず404が表示されたり、リロード耐性が失われることを避けることができる。

app
├── layout.tsx
├── page.tsx
├── default.tsx
└── @tab
    ├── page.tsx
    ├── default.tsx
    └── new
        └── page.tsx