Next.jsでParallel RoutesとIntercepting Routesを使ったモーダル実装
Next.jsのParallel Routes(並行ルート)とIntercepting Routes(インターセプトルート)を組み合わせて、モーダルを実装する方法を紹介します。
サンプルアプリケーション
Dog APIを使用した犬の一覧ページを作成しました。
デモ: https://practice-app-router-routes.vercel.app/
リポジトリ: https://github.com/k-logic563/practice-app-router-routes
主な機能
- 犬画像をクリックするとモーダルが表示される
- モーダル表示中にリロードすると詳細ページに遷移する
- URLはモーダル表示時も詳細ページと同じ
Parallel Routes(並行ルート)
公式ドキュメント: https://nextjs.org/docs/app/building-your-application/routing/parallel-routes
概要
複数のページを1つのレイアウト内に同時、または条件付きでレンダリングできる機能です。
基本ルール
- フォルダ名の先頭に
@をつける(例:@modal) - 表示させたいページまでのセグメント構造を合わせる
-
layout.tsxからスロット名を指定して使用する
実装例
詳細ページにモーダルを表示するため、@modal/dogs/[breed]/[id]/page.tsxを作成し、layout.tsxでスロット名(modal)を指定します。
この設定で/dogs/[breed]/[id]にアクセスするとモーダルが表示されますが、詳細ページに直接遷移してもモーダルが表示されてしまいます。この問題を解決するのがIntercepting Routesです。
Intercepting Routes(インターセプトルート)
公式ドキュメント: https://nextjs.org/docs/app/building-your-application/routing/intercepting-routes
概要
ルートをインターセプト(横取り)できる機能です。現在のレイアウト内で別のルートのコンテンツを読み込めます。
基本ルール
- 対象ディレクトリの先頭に
(..)をつける - カッコ内は対象ディレクトリまでの相対パスを表す
実装例
@modal/(.)dogs/[breed]/[id]とすることで、/dogs/[breed]/[id]にアクセスした際に詳細ページを表示せずにモーダルのみを表示できます。
仕組みの整理
実装の流れを整理すると以下のようになります。
- 画像クリック時に詳細ページのURLに変更する(例:
/dogs/shiba/123) - Intercepting Routesがルートを横取りし、詳細ページの代わりにモーダルコンポーネントをロードする
- Parallel Routesがモーダルを現在のレイアウト内に表示する
- リロード(ハードナビゲーション)すると、インターセプトが機能せず通常の詳細ページが表示される
この2つの機能を組み合わせることで、URLは詳細ページを指しながら、モーダル表示を実現しています。
まとめ
Parallel RoutesとIntercepting Routesを組み合わせることで、以下のようなUXを実現できます。
- モーダル表示中も適切なURLを保持
- リロード時には詳細ページに遷移
- ブラウザの戻るボタンでモーダルを閉じる
複雑なレイアウトやナビゲーションを実現する際に非常に有用な機能です。ぜひ活用してみてください。
Discussion