Storybook Addon React Router v6

Use React Router v6 in your stories.
✨Notice ✨
The old package name storybook-addon-react-router-v6 has been revived to exclusively support React Router v6 with new versions of Storybook going forward.
This will exist alongside the current storybook-addon-remix-react-router package, which supports Remix React Router and React Router v7.
The migration is mandatory to support Storybook 9.
Recent changes
✅ Support for Storybook 9 with storybook-addon-react-router-v6@4.
Getting Started
Install the package
npm i -D storybook-addon-remix-react-router
Add it to your storybook configuration:
export default {
addons: ['storybook-addon-remix-react-router'],
} satisfies StorybookConfig;
Decorate all stories of a component
To add the router to all the stories of a component, simply add it to the decorators array.
Note that parameters.reactRouter is optional, by default the router will render the component at /.
import { withRouter, reactRouterParameters } from 'storybook-addon-remix-react-router';
export default {
title: 'User Profile',
render: () => <UserProfile />,
decorators: [withRouter],
parameters: {
reactRouter: reactRouterParameters({
location: {
pathParams: { userId: '42' },
},
routing: { path: '/users/:userId' },
}),
},
};
Decorate a specific story
To change the config for a single story, you can do the following :
import { withRouter, reactRouterParameters } from 'storybook-addon-remix-react-router';
export default {
title: 'User Profile',
render: () => <UserProfile />,
decorators: [withRouter],
};
export const FromHomePage = {
parameters: {
reactRouter: reactRouterParameters({
location: {
pathParams: { userId: '42' },
searchParams: { tab: 'activityLog' },
state: { fromPage: 'homePage' },
},
routing: {
path: '/users/:userId',
handle: 'Profile',
},
}),
},
};
Decorate all stories, globally
To wrap all your project's stories inside a router by adding the decorator in your preview.js file.
export default {
decorators: [withRouter],
parameters: {
reactRouter: reactRouterParameters({ ... }),
}
} satisfies Preview;
Location
To specify anything related to the browser location, use the location property.
type LocationParameters = {
path?: string | ((inferredPath: string, pathParams: Record<string, string>) => string | undefined);
pathParams?: PathParams;
searchParams?: ConstructorParameters<typeof URLSearchParams>[0];
hash?: string;
state?: unknown;
};
Inferred path
If location.path is not provided, the browser pathname will be generated using the joined paths from the routing property and the pathParams.
Path as a function
You can provide a function to path.
It will receive the joined paths from the routing property and the pathParams as parameters.
If the function returns a string, is will be used as is. It's up to you to call generatePath from react-router if you need to.
If the function returns undefined, it will fallback to the default behavior, just like if you didn't provide any value for location.path.
Routing
You can set routing to anything accepted by createBrowserRouter.
To make your life easier, storybook-addon-remix-react-router comes with some routing helpers :
export const MyStory = {
parameters: {
reactRouter: reactRouterParameters({
routing: reactRouterOutlet(<MyOutlet />),
}),
},
};
Routing Helpers
The following helpers are available out of the box :
reactRouterOutlet();
reactRouterOutlets();
reactRouterNestedOutlets();
reactRouterNestedAncestors();
You can also create your own helper and use the exported type RoutingHelper to assist you :
import { RoutingHelper } from 'storybook-addon-remix-react-router';
const myCustomHelper: RoutingHelper = () => {
};
RouterRoute is basically the native RouteObject from react-router; augmented with { useStoryElement?: boolean }.
If you want to accept a JSX and turn it into a RouterRoute, you can use the exported function castRouterRoute.
Use the story as the route element
Just set { useStoryElement: true } in the routing config object.
Dedicated panel
Navigation events, loader and actions are logged, for you to better understand the lifecycle of your components.

Compatibility
This package aims to support Storybook > 7 and React > 16.
Here is a compatibility table :
| 4.x | >= 16.8.0 | 9.x | 6.x 1 |
| 3.x | >= 16.8.0 | 8.x | 6.x 1 |
| 2.x | >= v16.8.0 < v19.0.0 | 7.x | 6.x |
| 1.x | >= v16.8.0 < v19.0.0 | 7.x | 6.x |
1 You can actually use react-router v7 if you import from react-router-dom and not react-router.
If you have an issue with any version, open an issue.
Contribution
Contributions are welcome.
Before writing any code, file an issue to showcase the bug or the use case for the feature you want to see in this addon.
License
This package is released under the Apache 2.0 license.