Skip to content

Instantly share code, notes, and snippets.

@elfico
Created September 29, 2024 09:37
Show Gist options
  • Save elfico/eb355ad61332bcad9bddf2e9755b8553 to your computer and use it in GitHub Desktop.
Save elfico/eb355ad61332bcad9bddf2e9755b8553 to your computer and use it in GitHub Desktop.
Implementing Breadcrumbs in React using React Router v6
import { useEffect, useState } from 'react';
import { Link, matchRoutes, useLocation } from 'react-router-dom';
interface IRoute {
name: string;
path: string;
}
const routes: IRoute[] = [
{
path: '/home',
name: 'Home',
},
{
path: '/home/about',
name: 'About',
},
{
path: '/users',
name: 'Users',
},
{
path: '/users/:id/edit',
name: 'Edit Users by Id',
},
];
const Breadcrumbs = () => {
const location = useLocation();
const [crumbs, setCrumbs] = useState<IRoute[]>([]);
const getPaths = () => {
const allRoutes = matchRoutes(routes, location);
const matchedRoute = allRoutes ? allRoutes[0] : null;
let breadcrumbs: IRoute[] = [];
if (matchedRoute) {
breadcrumbs = routes
.filter((x) => matchedRoute.route.path.includes(x.path))
.map(({ path, ...rest }) => ({
path: Object.keys(matchedRoute.params).length
? Object.keys(matchedRoute.params).reduce(
(path, param) => path.replace(`:${param}`, matchedRoute.params[param] as string),
path
)
: path,
...rest,
}));
}
setCrumbs(breadcrumbs);
};
useEffect(() => {
getPaths();
}, [location]);
const goBack = () => {
window.history.back();
};
return (
<div className=''>
<nav aria-label='breadcrumb'>
<ol className='breadcrumb'>
<li className='breadcrumb-item pointer' onClick={goBack}>
<span className='bi bi-arrow-left-short me-1'></span>
Back
</li>
{crumbs.map((x: IRoute, key: number) =>
crumbs.length === key + 1 ? (
<li className='breadcrumb-item'>{x.name}</li>
) : (
<li className='breadcrumb-item'>
<Link to={x.path} className=' text-decoration-none'>
{x.name}
</Link>
</li>
)
)}
</ol>
</nav>
</div>
);
};
export default Breadcrumbs;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment