I am working with react-router-dom v6.8.1 (newest version as of now), and previously had a working breadcrumb setup using this third-party lib called use-react-router-breadcrumbs, but according to it's doc, they are now instead remending doing it the "built-in react-router way", that is documented here. It's based on attaching a crumb to the handle object of each route, and retrieve it using the useMatches
hook.
So I rewrote the code, but it has a quite major flaw that I cannot get around. Say that I have 3 routes, where 2 and 3 is nested below 1:
{
path: '/',
element: <Layout />,
handle: {
crumb: () => 'Home',
},
children: [
{
path: '/users',
element: <UserList />,
handle: {
crumb: () => 'Users',
},
},
{
path: '/users/:id',
element: <UserDetails />,
handle: {
crumb: () => <DynamicUserNameCrumb />,
},
},
]
}
With the custom lib you can go to /users/:id
and get a breadcrumb for each one of these routes, making the entire breadcrumbs look like:
"Home -> Users -> John Doe"
However, when using the new built-in way with the useMatches()
hook, I only get a match on route 1 and 3. Route 2 (/users) is not considered a match, and I cannot access the crumb for that route. Result is this, which is not what I want:
"Home -> John Doe"
So my question is: How are you supposed to handle this kind of situation? Nesting route 3 under 2 was my first idea, and this made the crumbs correct, but then it actually renders the ponent defined for route 2 (User list), and I only want it to render route 1 (layout) and 3 (User details page).
I was hoping that maybe useMatches()
would be able to accept configuration for also returning partial matches, but it seems that this hook does not accept any input.
I am close to reverting and going back to the third party lib, but wanted to ask here before I do so, since they explicitly remended using the native solution based on useMatches
and a handle
object. I figured there must be a solution for this if this is the officially remended way to handle breadcrumbs in react-router
I am working with react-router-dom v6.8.1 (newest version as of now), and previously had a working breadcrumb setup using this third-party lib called use-react-router-breadcrumbs, but according to it's doc, they are now instead remending doing it the "built-in react-router way", that is documented here. It's based on attaching a crumb to the handle object of each route, and retrieve it using the useMatches
hook.
So I rewrote the code, but it has a quite major flaw that I cannot get around. Say that I have 3 routes, where 2 and 3 is nested below 1:
{
path: '/',
element: <Layout />,
handle: {
crumb: () => 'Home',
},
children: [
{
path: '/users',
element: <UserList />,
handle: {
crumb: () => 'Users',
},
},
{
path: '/users/:id',
element: <UserDetails />,
handle: {
crumb: () => <DynamicUserNameCrumb />,
},
},
]
}
With the custom lib you can go to /users/:id
and get a breadcrumb for each one of these routes, making the entire breadcrumbs look like:
"Home -> Users -> John Doe"
However, when using the new built-in way with the useMatches()
hook, I only get a match on route 1 and 3. Route 2 (/users) is not considered a match, and I cannot access the crumb for that route. Result is this, which is not what I want:
"Home -> John Doe"
So my question is: How are you supposed to handle this kind of situation? Nesting route 3 under 2 was my first idea, and this made the crumbs correct, but then it actually renders the ponent defined for route 2 (User list), and I only want it to render route 1 (layout) and 3 (User details page).
I was hoping that maybe useMatches()
would be able to accept configuration for also returning partial matches, but it seems that this hook does not accept any input.
I am close to reverting and going back to the third party lib, but wanted to ask here before I do so, since they explicitly remended using the native solution based on useMatches
and a handle
object. I figured there must be a solution for this if this is the officially remended way to handle breadcrumbs in react-router
1 Answer
Reset to default 5From what I can tell it is because "/users"
and "/users/:id"
are sibling routes. Refactor the routes config such that "/users/:id"
is a child route of "/users"
so there's a "logical path" and individual segments from "/"
to "users"
to ":id"
.
Example:
const router = createBrowserRouter([
{
path: "/",
element: <Layout />,
handle: {
crumb: () => "Home"
},
children: [
{
path: "/users",
handle: {
crumb: () => "Users"
},
children: [
{
index: true,
element: <UserList />
},
{
path: "/users/:id",
element: <UserDetails />,
handle: {
crumb: () => <DynamicUserNameCrumb />
}
}
]
}
]
}
]);