Skip to content

Instantly share code, notes, and snippets.

@justincy
Last active April 5, 2024 22:19
Show Gist options
  • Save justincy/b8805ae2b333ac98d5a3bd9f431e8f70 to your computer and use it in GitHub Desktop.
Save justincy/b8805ae2b333ac98d5a3bd9f431e8f70 to your computer and use it in GitHub Desktop.
Configure Storybook to work with Next.js, TypeScript, and CSS Modules

In addition to the Storybook for React setup, you'll also need to install these packages:

npm i -D @babel/core babel-loader css-loader style-loader
const path = require('path');
module.exports = {
stories: ['../stories/**/*.stories.js', '../stories/**/*.stories.tsx'],
addons: ['@storybook/addon-actions', '@storybook/addon-links'],
presets: [path.resolve(__dirname, './next-preset.js')]
};
const path = require('path');
module.exports = {
webpackFinal: async (baseConfig, options) => {
// Modify or replace config. Mutating the original reference object can cause unexpected bugs.
const { module = {} } = baseConfig;
const newConfig = {
...baseConfig,
module: {
...module,
rules: [...(module.rules || [])]
}
};
// TypeScript with Next.js
newConfig.module.rules.push({
test: /\.(ts|tsx)$/,
include: [
path.resolve(__dirname, '../components'),
path.resolve(__dirname, '../stories')
],
use: [
{
loader: 'babel-loader',
options: {
presets: ['next/babel'],
plugins: ['react-docgen']
}
}
]
});
newConfig.resolve.extensions.push('.ts', '.tsx');
//
// CSS Modules
// Many thanks to https://github.com/storybookjs/storybook/issues/6055#issuecomment-521046352
//
// First we prevent webpack from using Storybook CSS rules to process CSS modules
newConfig.module.rules.find(
rule => rule.test.toString() === '/\\.css$/'
).exclude = /\.module\.css$/;
// Then we tell webpack what to do with CSS modules
newConfig.module.rules.push({
test: /\.module\.css$/,
include: path.resolve(__dirname, '../components'),
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true
}
}
]
});
return newConfig;
}
};
// If you need global CSS, you can import it here and Storybook will automatically include it in all stories.
// You don't need this if you don't have any global CSS.
import '../src/styles.css';
@kimizuy
Copy link

kimizuy commented Oct 17, 2021

@justincy Thank you for your guide!

I made a minimal example using Next.js(v11) + Storybook(v6.3) + CSS Modules.
It works with .module.css and .module.scss.
with-storybook-css-modules-app

It is configured with webpack5 (note: storybook is experimental now).
I'm referring to @joebartels' configuration. Thanks!

// .storybook/main.js
const path = require('path')

module.exports = {
  stories: ['../stories/*.stories.@(ts|tsx|js|jsx|mdx)'],
  addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
  webpackFinal: async (config) => {
    config.module.rules.push({
      test: /\.scss$/,
      use: [
        'style-loader',
        {
          loader: 'css-loader',
          options: {
            modules: {
              auto: true,
            },
          },
        },
        'sass-loader',
      ],
      include: path.resolve(__dirname, '../'),
    })
    return config
  },
  core: {
    builder: 'webpack5',
  },
}

@natterstefan
Copy link

Thank you @joebartels, I've one question left regarding your config. Does your config also support *.module.css files or only *.module.scss. I ran into several issues when trying to work with *.module.scss in my next-scss-tailwind-postcss setup when using modules that do not need to be .scss files necessarily.

FTR: In the end I renamed all my *.module.css files, but I wonder what's happening here. It worked without issues in next itself. 🤷

@tidusia
Copy link

tidusia commented Dec 7, 2021

For those who do not need Sass, I created an example repo with Next.js + Storybook + Tailwind + CSS Module support that does not require to modify the webpackFinal config.

Here is a git diff that focus on the setup.

@Pipe-Runner
Copy link

@tidusia Thanks, your config worked like a charm. I have one question though, why is babel-core and babel-loader needed as mentioned in your diff.

Also, I would like to point out, that if you are using path aliases via typescript, be sure to check this part of the documentation:
https://storybook.js.org/docs/riot/configure/webpack#typescript-module-resolution

@hieuvecto
Copy link

you saved my day

Copy link

ghost commented May 4, 2023

Amazing, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment