Storybook-tailwind. How should I add tailwind to storybook

26,279

Solution 1

Storybook recommends using the @storybook/addon-postcss for customizing the postCSS config from now on (instead of relying on customizing the postcss-loader):

  1. Add the postCSS addon to your installation

    npm i -D @storybook/addon-postcss     # or
    yarn add -D @storybook/addon-postcss
    
  2. Create the postcss.config.js in the project root

    // postcss.config.js
    module.exports = {
      plugins: {
        tailwindcss: {},
        autoprefixer: {},
      }
    }
    
  3. Add the plugin to your .storybook/main.js

    // .storybook/main.js
    module.exports = {
      ...
      addons: [
        ...
        {
          name: '@storybook/addon-postcss',
          options: {
            cssLoaderOptions: {
              // When you have splitted your css over multiple files
              // and use @import('./other-styles.css')
              importLoaders: 1,
            },
            postcssLoaderOptions: {
              // When using postCSS 8
              implementation: require('postcss'),
            },
          },
        },
      ],
    };
    
  4. Import your css file in the .storybook/preview.js

    // .storybook/preview.js
    import '../src/styles.css';
    

Solution 2

You're almost there.

The missing piece of your config is to add a webpack configuration to apply tailwind to postcss-loader:

const path = require('path')

module.exports = {
  stories: [
    '../src/**/*.stories.mdx', 
    '../src/**/*.stories.@(js|jsx|ts|tsx)'
  ],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/preset-create-react-app',
  ],
  webpackFinal: async (config) => {
    config.module.rules.push({
      test: /\.css$/,
      use: [
        {
          loader: 'postcss-loader',
          options: {
            postcssOptions: {
              plugins: [
                require('tailwindcss'),
                require('autoprefixer'),
              ],
            },
          },
        },
      ],
      include: path.resolve(__dirname, '../'),
    })
    return config
  },
}

Solution 3

The answer was right but in the latest CRA I have to config like this:

config.module.rules.push({
      test: /\.css$/,
      use: [
        {
          loader: "postcss-loader",
          options: {
            // HERE: OPTIONS
            postcssOptions: {
              plugins: [require("tailwindcss"), require("autoprefixer")],
            },
          },
        },
      ],
      include: path.resolve(__dirname, "../"),
    });

Solution 4

Similar to ofhouse's answer, but here is a solution if you don't want to have an extra postcss.config.js for only a few lines or if you want use typescript in everything (as the loader doesn't pick up postcss.config.ts)

  1. Add the official postCSS addon
npm i -D @storybook/addon-postcss
yarn add -D @storybook/addon-postcss
  1. Config main.ts & tailwind.config.ts
/* .stories/main.ts */

import postcss from 'postcss';
import * as tailwindcss from '../tailwind.config';

import type { StorybookConfig } from '@storybook/react/types';

export const addons: StorybookConfig['addons'] = [
  // other addons,
  {
    name: '@storybook/addon-postcss',
    options: {
      postcssLoaderOptions: {
        implementation: postcss,
        postcssOptions: {
          plugins: {
            tailwindcss, // or you can nest your options entirely here
            autoprefixer: {
              // autoprefixer options
            },
          },
        },
      },
    },
  },
];
/* tailwind.config.ts */

import type { TailwindConfig } from 'tailwindcss/tailwind-config';

export const theme: TailwindConfig['theme'] = {
  // theme options
}

// other options
Share:
26,279

Related videos on Youtube

Nivekithan
Author by

Nivekithan

Updated on April 15, 2022

Comments

  • Nivekithan
    Nivekithan about 2 years

    I want to add tailwind to storybook. So that Stories will render just like it will render on web.

    I used create-react-app project-name --template typescript to create the project.

    Then to install the tailwind I followed this https://tailwindcss.com/docs/guides/create-react-app instruction from the documentation of tailwind.

    Once I finished it I ran the code npm sb init. Which made sure that storybook ran.

    Now I need to tell storybook to use tailwindcss for styling. But I have no idea how.

    Every other answer I saw tells to edit postcss.config.js files.

    But I followed this https://tailwindcss.com/docs/guides/create-react-app documentation where I didnt even have to create postcss.config.js file. So I am confused to what to do now.

    For clarity I will include some configuration file below.

    craco.config.js

    module.exports = {
        style: {
          postcss: {
            plugins: [
              require('tailwindcss'),
              require('autoprefixer'),
            ],
          },
        },
      }
    
    

    .storybook/preview.js

    import "../src/index.css"
    
    export const parameters = {
      actions: { argTypesRegex: "^on[A-Z].*" },
    }
    

    .storybook/main.js

    module.exports = {
      "stories": [
        "../src/**/*.stories.mdx",
        "../src/**/*.stories.@(js|jsx|ts|tsx)"
      ],
      "addons": [
        "@storybook/addon-links",
        "@storybook/addon-essentials",
        "@storybook/preset-create-react-app"
      ]
    }
    

    src/index.css

    @tailwind base;
    @tailwind components;
    @tailwind utilities;
    

    tailwind.config.js

    module.exports = {
      purge: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'],
    
      darkMode: false, // or 'media' or 'class'
      theme: {
        extend: {},
      },
      variants: {
        extend: {},
      },
      plugins: [],
    }
    

    package.json

    `{
      "name": "memory",
      "version": "0.1.0",
      "private": true,
      "dependencies": {
        "@craco/craco": "^6.0.0",
        "@tailwindcss/postcss7-compat": "^2.0.2",
        "@testing-library/jest-dom": "^5.11.4",
        "@testing-library/react": "^11.1.0",
        "@testing-library/user-event": "^12.1.10",
        "@types/jest": "^26.0.15",
        "@types/node": "^12.0.0",
        "@types/react": "^16.14.2",
        "@types/react-dom": "^16.9.8",
        "autoprefixer": "^9.8.6",
        "postcss": "^7.0.35",
        "react": "^17.0.1",
        "react-dom": "^17.0.1",
        "react-scripts": "4.0.1",
        "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.2",
        "typescript": "^4.0.3",
        "web-vitals": "^0.2.4"
      },
      "scripts": {
        "start": "craco start",
        "build": "craco build",
        "test": "craco test",
        "eject": "react-scripts eject",
        "storybook": "start-storybook -p 6006 -s public",
        "build-storybook": "build-storybook -s public"
      },
      "eslintConfig": {
        "extends": [
          "react-app",
          "react-app/jest"
        ]
      },
      "browserslist": {
        "production": [
          ">0.2%",
          "not dead",
          "not op_mini all"
        ],
        "development": [
          "last 1 chrome version",
          "last 1 firefox version",
          "last 1 safari version"
        ]
      },
      "devDependencies": {
        "@storybook/addon-actions": "^6.1.11",
        "@storybook/addon-essentials": "^6.1.11",
        "@storybook/addon-links": "^6.1.11",
        "@storybook/node-logger": "^6.1.11",
        "@storybook/preset-create-react-app": "^3.1.5",
        "@storybook/react": "^6.1.11"
      }
    }
    
    

    tsconfig.json

    {
      "compilerOptions": {
        "target": "es5",
        "lib": [
          "dom",
          "dom.iterable",
          "esnext"
        ],
        "allowJs": true,
        "skipLibCheck": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "noFallthroughCasesInSwitch": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "noEmit": true,
        "jsx": "react-jsx"
      },
      "include": [
        "src"
      ]
    }
    
    
  • orimdominic
    orimdominic over 3 years
    Maybe you should create a boilerplate for this
  • Ala Douagi
    Ala Douagi over 3 years
    Oops, I just had to add import "../src/index.css" in .storybook/preview.js 😁
  • Fabien Greard
    Fabien Greard about 3 years
    @sudo_kaizen I added a storybook design system to a boilerplate I maintain, maybe this could help
  • kylejw2
    kylejw2 about 3 years
    Which version of postcss-loader should I use with a React library? I ran npm install postcss-loader but am getting an error in the loader function of postcss-loader/dist/index.js saying that this.getOptions is not a function.
  • andras
    andras about 3 years
    Check this out for newer postcss versions
  • allamgr
    allamgr about 3 years
    How can I use tailwind and postcss without webpack? Also using rollup to export the library.
  • wozniaklukasz
    wozniaklukasz about 3 years
    I also had to add import "../src/index.css" in .storybook/preview.js like @AlaDouagi to make it works.
  • Rohmer
    Rohmer almost 3 years
    This did not work for me in latest CRA. The accepted answer works fine.
  • cgat
    cgat over 2 years
    This didn't work for me for some reason. FWIW, I'm using postcss7 as this is recommended in the install page on tailwind. ``` SyntaxError (1:1) Unknown word > 1 | var api = require("!../node_modules/style-loader/dist/runtime/injectSt‌​ylesIntoStyleTag.js"‌​); | ^ 2 | var content = require("!!../node_modules/css-loader/dist/cjs.js??ref--10-1‌​!../node_modules/pos‌​tcss-loader/dist/cjs‌​.js!./index.css"); ```
  • ofhouse
    ofhouse over 2 years
    Tailwind requires PostCSS 8 (not 7) as stated in the docs: tailwindcss.com/docs/installation#install-tailwind-via-npm
  • sairaj
    sairaj over 2 years
    it's not working for me
  • cgat
    cgat over 2 years
    CRA doesn't support PostCSS 8 though, so you need to install a postcss 7 compat build: tailwindcss.com/docs/guides/create-react-app
  • John McCollum
    John McCollum over 2 years
    I had to import the CSS and change the options field as follows: options: { postcssOptions: { plugins: [require("tailwindcss"), require("autoprefixer")]}} See this link for details, and sorry for the formatting!
  • Andresch Serj
    Andresch Serj about 2 years
    @cgat How do i install a postcss 7 compatible build?
  • cgat
    cgat about 2 years
    The tailwindcss link above used to describe how to do this (they had a special postcss7 compat build you would install. Looks like things might have changed and potentially postcss 8 is now supported.
  • Mu Mind
    Mu Mind almost 2 years
    Confirmed, like @JohnMcCollum I got it working after changing to nested postcssOptions and getting rid of ident. Could you update this answer for 2022?
  • Mu Mind
    Mu Mind almost 2 years
    I could NOT get addon-postcss working in 2022, but the webpackFinal config from the top voted answer did work. I kept getting "Unknown word" errors like github.com/storybookjs/addon-postcss/issues/33 no matter what config I tried, and agree with the comment there that it's basically abandoned (tons of neglected issues and no commits in 16 months).