10. intercepting routes
intercepting routes を利用して、intagaram like な遷移を実現してみましょう。
ここでいう、intagaram like な遷移とは下記のようなものです。
- 一覧ページから詳細のページに遷移する際には、URLを詳細のページに変更しつつ、一覧のページにモーダルのような形で詳細の情報を表示する
- 詳細ページに直接アクセスされた場合には、詳細だけのページを表示する
Next.js の 前回の parallel routes とあわせて intercepting routes を利用することで、このような挙動を実現することができます。
実装する
まずは、モーダルを表示するために、parallel routes を追加します。
mkdir -p "apps/workspace/app/(dashboard)/@modal"touch "apps/workspace/app/(dashboard)/@modal/default.tsx"
//apps/workspace/app/(dashboard)/@modal/default.tsxexport default function Default() { return null;}
次に Layout を更新します。
//apps/solution/app/(dashboard)/layout.tsx
export default function dashboardLayout(props: { children: React.ReactNode; header: React.ReactNode; modal: React.ReactNode;}) {
... {props.modal} </main> );}
最後に、intercepting routes を追加してみましょう。
mkdir -p "apps/workspace/app/(dashboard)/@modal/(.)inbox/[id]"touch "apps/workspace/app/(dashboard)/@modal/(.)inbox/[id]/page.tsx"
//apps/workspace/app/(dashboard)/@modal/(.)inbox/[id]/page.tsximport { MailViewer } from "@/components/mail-viewer";import type { MailData } from "@/lib/types";import Link from "next/link";import { Suspense } from "react";
export default function QuickMailViewModal(props: { params: { id: string; };}) { return ( <> <Link className="absolute inset-0 backdrop-brightness-50 z-modal" href="/inbox" /> <div className="absolute right-0 top-0 bottom-0 m-auto bg-white border rounded-l-lg w-3/5 z-modal"> <Suspense fallback={<div className="text-center mt-10">Loading...</div>} > <Mail id={props.params.id} /> </Suspense> </div> </> );}
async function Mail(props: { id: string }) { const res = (await fetch(`http://localhost:8000/inbox/${props.id}`, { cache: "no-cache", }).then((res) => res.json())) as MailData;
return <MailViewer mail={res} />;}
これで詳細がモーダルのように表示されるようになりました。
実際にhttp://localhost:3000/inbox
にアクセスして確認してみましょう。
仕上げ
実は、このままだとモーダルが閉じません。
戻るボタンやグレーな部分をクリックすると/inbox
に遷移するようになっています。
URLは変わっていますが、画面は変わっていません。なぜでしょうか?
.
.
.
前回のないようにある通り parallel routes
がソフトナビゲーションした際に、/inbox
にマッチするサブページ(@modal/inbox/page.tsx)がないため、サブページとして表示しているモーダルが表示され続けているためです。
仕上げとして、apps/solution/app/(dashboard)/@modal/inbox/page.tsx
を追加してみましょう。
mkdir -p "apps/workspace/app/(dashboard)/@modal/inbox"touch "apps/workspace/app/(dashboard)/@modal/inbox/page.tsx"
//apps/workspace/app/(dashboard)/@modal/inbox/page.tsxexport default function Page() { return null;}
これで閉じられるようになりました。
まとめ
intercepting routes を利用することで、特定のページの遷移を intercept して、違う内容を表示することができます。
また、parallel routes とあわせて利用することで、modal のような挙動を実現することができます。