React - Breadcrumbs Navigation
Overview
Estimated time: 10–20 minutes
Show users where they are in the app by deriving breadcrumbs from the current route.
Try it: Breadcrumbs from hash
View source
function usePath(){
const [path, setPath] = React.useState(() => location.hash.replace('#','') || '/');
React.useEffect(() => { const on=()=> setPath(location.hash.replace('#','') || '/'); addEventListener('hashchange', on); return ()=> removeEventListener('hashchange', on); }, []);
return path;
}
function Crumbs(){
const path = usePath();
const parts = path.split('/').filter(Boolean);
const crumbs = parts.map((p,i) => ({ label: decodeURIComponent(p), to: '#/'+ parts.slice(0,i+1).join('/') }));
return (
<nav aria-label="Breadcrumb">
<a href="#/">Home</a>
{crumbs.map((c,i) => <span key={i}> / <a href={c.to}>{c.label}</a></span>)}
</nav>
);
}
function App(){
return (
<div>
<Crumbs />
<div style={{marginTop:8}}>
<a href="#/products">/products</a> | <a href="#/products/42">/products/42</a> | <a href="#/products/42/reviews">/products/42/reviews</a>
</div>
</div>
);
}
ReactDOM.createRoot(document.getElementById('try-crumbs')).render(<App />);
Syntax primer
- Split the path into parts and build cumulative links.
Common pitfalls
- Not decoding components—use decodeURIComponent for readability.
Exercises
- Replace labels with friendly titles by mapping route segments to titles.
Checks for Understanding
- How are breadcrumb links derived from the current path?
- Why is decodeURIComponent used when rendering breadcrumb labels?
- How do you make the breadcrumb nav accessible?
Answers
- Split the pathname into segments, then build cumulative links for each segment (/a, /a/b, /a/b/c).
- To display human-friendly titles when the URL contains encoded characters (spaces, unicode, etc.).
- Wrap links in a nav with aria-label="Breadcrumb" and include the Home link; separators can be visually rendered without being part of the link text.