Gathering detailed insights and metrics for storybook-addon-next
Gathering detailed insights and metrics for storybook-addon-next
Gathering detailed insights and metrics for storybook-addon-next
Gathering detailed insights and metrics for storybook-addon-next
storybook-addon-next-router
Use Next.js Router in your Storybook stories.
@storybook/addon-toolbars
Create your own toolbar items that control story rendering
@storybook/addon-essentials
Curated addons to bring out the best of Storybook
@storybook/addon-actions
Get UI feedback when an action is performed on an interactive element
A no config Storybook addon that makes Next.js features just work in Storybook
npm install storybook-addon-next
53.9
Supply Chain
53.9
Quality
73.9
Maintenance
50
Vulnerability
97.3
License
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
219 Stars
142 Commits
29 Forks
4 Watching
5 Branches
7 Contributors
Updated on 08 Aug 2024
TypeScript (98.54%)
Shell (1.21%)
JavaScript (0.25%)
Cumulative downloads
Total Downloads
Last day
10.4%
5,814
Compared to previous day
Last week
19.3%
31,800
Compared to previous week
Last month
4.1%
124,580
Compared to previous month
Last year
-59.1%
2,124,602
Compared to previous year
8
5
24
This addon has been deprecated in favor of @storybook/nextjs which is the Storybook official addon for supporting Next.js features in Storybook. It supports everything storybook-addon-next
does and much more! I even worked on developing this with them so you should be in good hands.
Consult the migration docs for details on how to migrate.
😱 No config support for Next.js: Tired of writing and debugging webpack config? What Next.js supports out of the box, this addon makes possible in Storybook
👉 Next.js's Image Component (partial support)
👉 Postcss
.js
extension and not the .mjs
extension (i.e. next.config.js
not next.config.mjs
)
To run any example, first build the addon by running
yarn build
in the root of this repo.
Install storybook-addon-next
using yarn
:
1yarn add --dev storybook-addon-next
Or npm
:
1npm install --save-dev storybook-addon-next
1// .storybook/main.js 2 3module.exports = { 4 // other config ommited for brevity 5 addons: [ 6 // ... 7 'storybook-addon-next' 8 // ... 9 ] 10}
🥳🎉 Thats it! The supported features should work out of the box.
See Documentation for more details on how the supported features work in this addon.
If something doesn't work as you would expect, feel free to open up an issue.
This addon can be passed an options object for addional configuration if needed.
For example:
1// .storybook/main.js 2const path = require('path') 3 4module.exports = { 5 // other config ommited for brevity 6 addons: [ 7 // ... 8 { 9 name: 'storybook-addon-next', 10 options: { 11 nextConfigPath: path.resolve(__dirname, '../next.config.js') 12 } 13 } 14 // ... 15 ] 16}
nextConfigPath
: The absolute path to the next.config.js
next/image is notoriously difficult to get working with storybook. This addon allows you to use Next.js's Image
component with no configuration!
Because the image component has features, like image optimization, configured by options that require the Next.js config file to be read and processed by the framework and there is no public function exposed by Next.js to resolve and those options, it is not possible to support those features stably.
If you want to see this better supported, feel free to contribute to the discussion on Next.js's side or the discussion on our side
Local images work just fine with this addon! Keep in mind that this feature was only added in Next.js v11.
1import Image from 'next/image' 2import profilePic from '../public/me.png' 3 4function Home() { 5 return ( 6 <> 7 <h1>My Homepage</h1> 8 <Image 9 src={profilePic} 10 alt="Picture of the author" 11 // width={500} automatically provided 12 // height={500} automatically provided 13 // blurDataURL="../public/me.png" set to equal the image itself (for this addon) 14 // placeholder="blur" // Optional blur-up while loading 15 /> 16 <p>Welcome to my homepage!</p> 17 </> 18 ) 19}
Remote images also work just fine!
1import Image from 'next/image' 2 3export default function Home() { 4 return ( 5 <> 6 <h1>My Homepage</h1> 7 <Image 8 src="/me.png" 9 alt="Picture of the author" 10 width={500} 11 height={500} 12 /> 13 <p>Welcome to my homepage!</p> 14 </> 15 ) 16}
All Next.js Image
s are automatically unoptimized for you.
If placeholder="blur" is used, the blurDataURL used is the src of the image (thus effectively disabling the placeholder).
See this issue for more discussion on how Next.js Image
s are handled for Storybook.
This format is not supported by this addon yet. Feel free to open up an issue if this is something you want to see.
This solution is heavily based on storybook-addon-next-router so a big thanks to lifeiscontent
for providing a good solution that this addon could work off of.
Next.js's router is automatically stubbed for you so that when the router is interacted with, all of its interactions are automatically logged to the Storybook actions tab if you have the actions addon.
Per-story overrides can be done by adding a nextRouter
property onto the story parameters. The addon will shallowly merge whatever you put here into the router.
1import SomeComponentThatUsesTheRouter from "./SomeComponentThatUsesTheRouter"; 2 3export default { 4 title: "My Story", 5}; 6 7// if you have the actions addon 8// you can click the links and see the route change events there 9export const Example = () => <SomeComponentThatUsesTheRouter />; 10 11Example.parameters: { 12 nextRouter: { 13 path: "/profile/[id]", 14 asPath: "/profile/ryanclementshax", 15 query: { 16 id: "ryanclementshax" 17 } 18 } 19}
See this example for a reference.
Global defaults can be set in preview.js and will be shallowly merged with the default router.
1export const parameters = { 2 nextRouter: { 3 path: '/some-default-path', 4 asPath: '/some-default-path', 5 query: {} 6 } 7}
See this example for a reference.
The default values on the stubbed router are as follows (see globals for more details on how globals work)
1const defaultRouter = { 2 locale: context?.globals?.locale, 3 route: '/', 4 pathname: '/', 5 query: {}, 6 asPath: '/', 7 push(...args: unknown[]) { 8 action('nextRouter.push')(...args) 9 return Promise.resolve(true) 10 }, 11 replace(...args: unknown[]) { 12 action('nextRouter.replace')(...args) 13 return Promise.resolve(true) 14 }, 15 reload(...args: unknown[]) { 16 action('nextRouter.reload')(...args) 17 }, 18 back(...args: unknown[]) { 19 action('nextRouter.back')(...args) 20 }, 21 prefetch(...args: unknown[]) { 22 action('nextRouter.prefetch')(...args) 23 return Promise.resolve() 24 }, 25 beforePopState(...args: unknown[]) { 26 action('nextRouter.beforePopState')(...args) 27 }, 28 events: { 29 on(...args: unknown[]) { 30 action('nextRouter.events.on')(...args) 31 }, 32 off(...args: unknown[]) { 33 action('nextRouter.events.off')(...args) 34 }, 35 emit(...args: unknown[]) { 36 action('nextRouter.events.emit')(...args) 37 } 38 }, 39 isFallback: false 40}
If you override a function, you lose the automatic action tab integration and have to build it out yourself.
1export const parameters = { 2 nextRouter: { 3 push() { 4 // we lose the default implementation that logs the action into the action tab 5 } 6 } 7}
Doing this yourself looks something like this (make sure you install the @storybook/addon-actions
package):
1import { action } from '@storybook/addon-actions' 2 3export const parameters = { 4 nextRouter: { 5 push(...args) { 6 // custom logic can go here 7 // this logs to the actions tab 8 action('nextRouter.push')(...args) 9 // return whatever you want here 10 return Promise.resolve(true) 11 } 12 } 13}
Global sass/scss stylesheets are supported without any additional configuration as well. Just import them into preview.js
1import '../styles/globals.scss'
This will automatically include any of your custom sass configurations in your next.config.js
file.
Right now only the
.js
extension of the Next.js config is supported, not.mjs
. See next.config.js for more details.
1const path = require('path') 2 3module.exports = { 4 // any options here are included in sass compilation for your stories 5 sassOptions: { 6 includePaths: [path.join(__dirname, 'styles')] 7 } 8}
Next.js supports css modules out of the box so this addon supports it too.
1// this import works just fine in Storybook now 2import styles from './Button.module.css' 3// sass/scss is also supported 4// import styles from './Button.module.scss' 5// import styles from './Button.module.sass' 6 7export function Button() { 8 return ( 9 <button type="button" className={styles.error}> 10 Destroy 11 </button> 12 ) 13}
The built in CSS in JS solution for Next.js is styled-jsx, and this addon supports that out of the box too, zero config.
1// This works just fine in Storybook with this addon 2function HelloWorld() { 3 return ( 4 <div> 5 Hello world 6 <p>scoped!</p> 7 <style jsx>{` 8 p { 9 color: blue; 10 } 11 div { 12 background: red; 13 } 14 @media (max-width: 600px) { 15 div { 16 background: blue; 17 } 18 } 19 `}</style> 20 <style global jsx>{` 21 body { 22 background: black; 23 } 24 `}</style> 25 </div> 26 ) 27} 28 29export default HelloWorld
You can use your own babel config too. This is an example of how you can customize styled-jsx.
1// .babelrc or whatever config file you use 2{ 3 "presets": [ 4 [ 5 "next/babel", 6 { 7 "styled-jsx": { 8 "plugins": ["@styled-jsx/plugin-sass"] 9 } 10 } 11 ] 12 ] 13}
If you use a monorepo, you may need to add the babel config yourself to your storybook project. Just add a babel config to your storybook project with the following contents to get started.
1{ 2 "presets": ["next/babel"] 3}
Next.js lets you customize postcss config. Thus this addon will automatically handle your postcss config for you.
This allows for cool things like zero config tailwindcss! See the with-tailwindcss example for reference! Its a clone of Next.js's tailwindcss example set up with storybook and this addon.
Goodbye ../
! Absolute imports from the root directory work just fine with this addon.
1// All good! 2import Button from 'components/button' 3// Also good! 4import styles from 'styles/HomePage.module.css' 5 6export default function HomePage() { 7 return ( 8 <> 9 <h1 className={styles.title}>Hello World</h1> 10 <Button /> 11 </> 12 ) 13}
1// preview.js 2 3// Also ok in preview.js! 4import 'styles/globals.scss' 5 6// ...
Next.js allows for Runtime Configuration which lets you import a handy getConfig
function to get certain configuration defined in your next.config.js
file at runtime.
In the context of Storybook with this addon, you can expect Next.js's Runtime Configuration feature to work just fine.
Note, because Storybook doesn't server render your components, your components will only see what they normally see on the client side (i.e. they won't see serverRuntimeConfig
but will see publicRuntimeConfig
).
For example, consider the following Next.js config:
1// next.config.js 2module.exports = { 3 serverRuntimeConfig: { 4 mySecret: 'secret', 5 secondSecret: process.env.SECOND_SECRET // Pass through env variables 6 }, 7 publicRuntimeConfig: { 8 staticFolder: '/static' 9 } 10}
Calls to getConfig
would return the following object when called within Storybook:
1{ 2 "serverRuntimeConfig": {}, 3 "publicRuntimeConfig": { 4 "staticFolder": "/static" 5 } 6}
Next.js comes with a lot of things for free out of the box like sass support, but sometimes we add custom webpack config modifications to Next.js. This addon takes care of most of the webpack modifications you would want to add. If Next.js supports a feature out of the box, then this addon will make that feature work out of the box in Storybook. If Next.js doesn't support something out of the box, but makes it easy to configure, then this addon will do the same for that thing for Storybook. If you find something that you still need to configure webpack to get a Next.js feature to work in Storybook after adding this addon, this is likely a bug and please feel free to open up an issue.
Any webpack modifications desired for Storybook should be made in .storybook/main.js according to Storybook's docs.
Note: Not all webpack modifications are copy/paste-able between next.config.js
and .storybook/main.js
. It is recommended to do your reasearch on how to properly make your modifcation to Storybook's webpack config and on how webpack works.
Please feel free to contribute an example to help out the community.
Below is an example of how to add svgr support to Storybook with this addon. The full example can be found here.
1// .storybook/main.js 2module.exports = { 3 // other config omitted for brevity 4 webpackFinal: async config => { 5 // this modifies the existing image rule to exclude .svg files 6 // since we want to handle those files with @svgr/webpack 7 const imageRule = config.module.rules.find(rule => rule.test.test('.svg')) 8 imageRule.exclude = /\.svg$/ 9 10 // configure .svg files to be loaded with @svgr/webpack 11 config.module.rules.push({ 12 test: /\.svg$/, 13 use: ['@svgr/webpack'] 14 }) 15 16 return config 17 } 18}
Storybook handles most Typescript configurations, but this addon adds additional support for Next.js's support for Absolute Imports and Module path aliases. In short, it takes into account your tsconfig.json
's baseUrl and paths. Thus, a tsconfig.json
like the one below would work out of the box.
1{ 2 "compilerOptions": { 3 "baseUrl": ".", 4 "paths": { 5 "@/components/*": ["components/*"] 6 } 7 } 8}
Right now the only supported config format for Next.js that this plugin supports is the commonjs version of the config (i.e. next.config.js
). This is mostly because I haven't figured out how to require a .mjs
file from a storybook addon (which is bound to commonjs modules as far as I know right now). If you are able to help, I'd love it if you could contribute to this discussion to get support for the .mjs
version if such support is even possible.
If you're using Yarn v2 or v3, you may run into issues where Storybook can't resolve style-loader
or css-loader
. For example, you might get errors like:
Module not found: Error: Can't resolve 'css-loader'
Module not found: Error: Can't resolve 'style-loader'
This is because those versions of Yarn have different package resolution rules than Yarn v1.x. If this is the case for you, just install the package directly.
Make sure you are treating image imports the same way you treat them when using next image in normal development.
Before storybook-addon-next
, image imports just imported the raw path to the image (e.g. 'static/media/stories/assets/plugin.svg'
). When using storybook-addon-next
image imports work the "Next.js way" meaning that we now get an object when we import an image. For example:
1{ 2 "src": "static/media/stories/assets/plugin.svg", 3 "height": 48, 4 "width": 48, 5 "blurDataURL": "static/media/stories/assets/plugin.svg" 6}
Therefore, if something in storybook isn't showing the image properly, make sure you expect the object to be returned from an import instead of just the asset path.
See local images for more detail on how Next.js treats static image imports.
Right now using next.config.mjs
isn't supported by this addon. See next.config.js for more details. Right now, it is required for you to use the .js
extension instead. Feel free to help out on this discussion to get this supported.
You might get this if you're using Yarn v2 or v3. See Notes for Yarn v2 and v3 users for more details.
I'm open to discussion. Feel free to open up an issue.
Was this documentation insufficient for you?
Was it confusing?
Was it ... dare I say ... inaccurate?
If any of the above describes your feelings of this documentation. Feel free to open up an issue.
No vulnerabilities found.
No security vulnerabilities found.