React Router Breadcrumbs HOC
A tiny (~2kb minified), flexible, higher order component for rendering breadcrumbs with react-router 4.x
site.com/user/id → Home / User / John Doe
Description
Deconstruct a route and return matching breadcrumb components you can render however you like. Render a simple string, a component that fetches a model in order to display the desired content, or just render something totally unrelated to the route.
We are currently using this method @ Koan Inc.
Note: Upgrading from 1.x.x
to 2.x.x
? Check out the guide here
Install
yarn add react-router-breadcrumbs-hoc
or
npm install react-router-breadcrumbs-hoc --save
Usage
withBreadcrumbs()(MyComponent);
Simple example
import React from 'react';
import { NavLink } from 'react-router-dom';
import withBreadcrumbs from 'react-router-breadcrumbs-hoc';
const UserBreadcrumb = ({ match }) =>
<span>{match.params.userId}</span>;
const routes = [
{ path: '/users/:userId', breadcrumb: UserBreadcrumb },
{ path: '/example', breadcrumb: 'Custom Example' },
];
const Breadcrumbs = ({ breadcrumbs }) => (
<div>
{breadcrumbs.map((breadcrumb, index) => (
<span key={breadcrumb.props.key}>
<NavLink to={breadcrumb.props.match.url}>
{breadcrumb}
</NavLink>
{(index < breadcrumbs.length - 1) && <i> / </i>}
</span>
))}
</div>
);
export default withBreadcrumbs(routes)(Breadcrumbs);
For the above example...
Pathname | Result |
---|
/users | Home / Users |
/users/id | Home / Users / John |
/example | Home / Custom Example |
Disabling default breadcrumbs for paths
This package will attempt to create breadcrumbs for you based on the route section via humanize-string. For example /users
will auotmatically create the breadcrumb "Users"
. There are two ways to disable default breadcrumbs for a path:
Pass breadcrumb: null
in the routes config:
{ path: '/a/b', breadcrumb: null }
Or, Pass an excludePaths
array in the options
object
withBreadcrumbs(routes, { excludePaths: ['/', '/no-breadcrumb/for-this-route'] })
in your routes array.
Already using a route config array with react-router?
Just add a breadcrumb
prop to your routes that require custom breadcrumbs.
Note: currently, nested route
s arrays are not supported, but will be soon (see: https://github.com/icd2k3/react-router-breadcrumbs-hoc/issues/24)
API
Route = {
path: String
breadcrumb: String|Function?
matchOptions?: Object
}
Options = {
excludePaths: Array
}
withBreadcrumbs(routes?: Array<Route>, options? Object<Options>): HigherOrderComponent
getBreadcrumbs({
routes: Array<Route>,
location: Object<Location>,
options: Object<Options>,
}): Array<Breadcrumb>
Order matters!
Consider the following route configs:
[
{ path: '/users/:id', breadcrumb: 'id-breadcrumb' },
{ path: '/users/create', breadcrumb: 'create-breadcrumb' },
]
To fix the issue above, just adjust the order of your routes:
[
{ path: '/users/create', breadcrumb: 'create-breadcrumb' },
{ path: '/users/:id', breadcrumb: 'id-breadcrumb' },
]
Using the location object
React Router's location object lets you pass state
property. Using the state
allows one to update the Breadcrumb to display dynamic info at runtime. Consider this example:
const Breadcrumb = ({ location: { state: { isNew } } }) => (
<span>{isNew ? 'Add New' : 'Update'}</span>
);
{
pathname: '/editor',
breadcrumb: Breadcrumb
...
}
<Link to={{ pathname: '/editor' }}>Edit</Link>
<Link to={{ pathname: '/editor', state: { isNew: true } }}>Add</Link>
Now, based on what you pass in the state
prop, the Breadcrumb will display dynamic values at runtime!