パンくずリスト(breadcrumb)とは、Webサイトの階層構造を表すリストのことです。
設置することで、ユーザーがWebサイトのどの位置にいるのかを把握するのに役立ちます。
パンくずナビゲーション – CSS: カスケーディングスタイルシート | MDN
今回は、Remixでパンくずリストを作る方法について解説します。
実装方法
Remixでは useMatches
、 定数handle
および Linkコンポーネント
を組み合わせて使用することで、ネストしたルーティングに対してパンくずリストを作ることができます。
具体的な手順は以下の通りです。
1. パンくずリストを追加したいページに「 Linkコンポーネント
を返す 定数handle
」を定義する
例えば app/routes/parent.tsx
と app/routes/parent.children.tsx
が存在するルーティングの場合、以下のような形でエクスポートします。
例: app/routes/parent.tsx
import { Link, Outlet } from "@remix-run/react";
// ...
export const handle = {
// キー名は任意ですが、わかりやすいので breadcrumnb としています
// 「to」に渡す値は自身へのパス名とし、任意の表示名がつけられます(ここでは 親ページ としています)
breadcrumb: () => <Link to="/parent">親ページ</Link>
}
例: app/routes/parent.children.tsx
import { Link } from "@remix-run/react";
// ...
export const handle = {
breadcrumb: () => <Link to="/parent/children">子供一覧ページ</Link>
}
2. useMatches
を使って、定義した 定数handle
を取得して中身をパンくずリストの形で表示するためのコンポーネントを追加する
例えば app/components/breadcrumb.tsx
というファイルを作成し、以下のようなコンポーネントを作成します。
例: app/components/breadcrumb.tsx
import { useMatches } from "@remix-run/react"
export const Breadcrumb = () => {
const matches = useMatches()
return (
<ol style={{ listStyle: "none" }}>
{
matches
.filter((match) => match.handle?.breadcrumb)
.map((match, index) => {
const separator = index === 0 ? null : ">"
return (
<li key={index} style={{ display: "inline-block" }}>
{separator && <span style={{ padding: "0 10px" }}>{separator}</span>}
{match.handle.breadcrumb(match)}
</li>
)
})
}
</ol>
)
}
3. ネストしたルーティングの親コンポーネント内でBreadcrumbコンポーネントを呼び出す
例えば app/routes/parent.tsx
および app/routes/parent.children.tsx
にパンくずリストを表示したい場合、app/routes/parent.tsx
に対して以下のように記述します。
例: app/routes/parent.tsx
import { Breadcrumb } from "~/components/breadcrumb";
// ...
export default function Parent() {
return (
<div>
<header>
{/* 追加したコンポーネントを表示(headerタグで囲んでいることには、特に意味はありません) */}
<Breadcrumb />
</header>
{/* ... */}
</div>
)
}
// ...
パンくずリストの作り方は公式ドキュメントにも「useMatchesの活用例」として紹介されているので、そちらも確認してみてください。