🚪

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]にアクセスした際に詳細ページを表示せずにモーダルのみを表示できます。

仕組みの整理

実装の流れを整理すると以下のようになります。

  1. 画像クリック時に詳細ページのURLに変更する(例: /dogs/shiba/123
  2. Intercepting Routesがルートを横取りし、詳細ページの代わりにモーダルコンポーネントをロードする
  3. Parallel Routesがモーダルを現在のレイアウト内に表示する
  4. リロード(ハードナビゲーション)すると、インターセプトが機能せず通常の詳細ページが表示される

この2つの機能を組み合わせることで、URLは詳細ページを指しながら、モーダル表示を実現しています。

まとめ

Parallel RoutesとIntercepting Routesを組み合わせることで、以下のようなUXを実現できます。

  • モーダル表示中も適切なURLを保持
  • リロード時には詳細ページに遷移
  • ブラウザの戻るボタンでモーダルを閉じる

複雑なレイアウトやナビゲーションを実現する際に非常に有用な機能です。ぜひ活用してみてください。

参考

Discussion