Next.js is a popular framework built on top of React that allows users to build React applications quickly and easily. At OpenSauced, we are working on a new project that leverages Next.js and Tailwind CSS. For this project we also wanted to build a design system to support this project and, potentially in the future, other OpenSauced projects.
To that end, we also decided to leverage Storybook to document our design system. Unfortunately, setting up Storybook with Next.js and Tailwind is not trivial and it took us some time to get things working properly. This article is for those looking to stand up a similar project and need help setting things up.
Outline
- Setting up the Next Tailwind CSS project
- Installing Storybook
- Configuring Storybook to use Tailwind
- Configuring Storybook to use Next
Setting up the Next Tailwind CSS project
Thankfully this part is fairly simple. To stand up a new Next.js project with Tailwind, run this command:
npx create-next-app -e with-tailwindcss next-tailwind-storybook-example
Note: The last keyword will be the name of your project.
Create-next-app will stand up a new Next.js project in TypeScript with Tailwind already pre-installed. Once the setup is completed, you can navigate to the folder where your Next.js project has been set up and run the command npm run dev
to start the Next.js dev server.
cd next-tailwind-storybook-example
npm run dev
This will let you view the project at localhost:3000 which will give you Next.js’s starter screen.
Installing Storybook
To set up Storybook within the Next.js project, run this command:
npx -y sb init --builder webpack5
This will initialize a new Storybook installation. It will automatically detect which type of application you are working on (in this case React) and install the necessary dependencies to get Storybook up and running.
Note: If you are using a version of npm above npm7, Storybook will ask if you would like to run the npm7 migration. Press ‘y’ to answer yes to run the migration. If you do not do this, you will have issues installing the other packages needed to continue this set up. If you skip this step by accident, run
npx storybook@next automigrate
to run the migration.
After the installation, you will be able to run Storybook. To run Storybook, use the command npm run storybook
and open localhost:6006.
npm run storybook
Outside of necessary config files, Storybook gives you starter stories to give you an idea of how to use it. Unfortunately, Storybook is not configured to use Tailwind out of the box and so we have to manually set that up ourselves.
Configuring Storybook to use Tailwind
To use Tailwind in Storybook, you’ll need to install an addon so that Storybook knows how to use Tailwind. First, run this command to download the addon to your project:
npm i -D @storybook/addon-postcss
Once the download is completed, open .storybook/main.js
in your Next.js project folder. This is a config file for Storybook and where you can install new addons to your project. In the addons
array, add @storybook/addon-postcss
:
// .storybook/main.js
module.exports = {
"stories": [
"../stories/**/*.stories.mdx",
"../stories/**/*.stories.@(js|jsx|ts|tsx)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/addon-postcss",
],
"framework": "@storybook/react",
"core": {
"builder": "@storybook/builder-webpack5"
}
}
This will allow Storybook to use this addon. Now open .storybook/preview.js
in your Next.js project folder. At the beginning of the file, add import "../styles/globals.css"
:
// .storybook/preview.js
import "../styles/globals.css"
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
}
Note:
globals.css
is a CSS file for Tailwind. If you have another file or have moved this file to a new location, you’ll need to import that file from the location you’ve moved it to.
Now you can run Storybook and you’ll be able to render components with Tailwind classes.
Configuring Storybook to use Next
Out of the box, Storybook will not be able to use Next-specific components and features, making the components work incorrectly when you try to view them in Storybook.
Fortunately, Storybook has provided an addon that allows us to use Next.js features within Storybook. First, you’ll need to download the addon. Run this command:
npm i storybook-addon-next
Once it is completed, return to .storybook/main.js
in your Next.js project. In the addons
array, similar to where you installed the previous addon, add storybook-addon-next
:
// .storybook/main.js
module.exports = {
"stories": [
"../stories/**/*.stories.mdx",
"../stories/**/*.stories.@(js|jsx|ts|tsx)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/addon-postcss",
"storybook-addon-next",
],
"framework": "@storybook/react",
"core": {
"builder": "@storybook/builder-webpack5"
}
}
Now if you were to run Storybook with npm run storybook
, you’d get an error from TypeScript saying that baseUrl
is missing from tsconfig.json
.
Found no baseUrl in tsconfig.json, not applying tsconfig-paths-webpack-plugin
This line was not automatically added to the tsconfig.json
file when the project was first stood up. Since it needs to be added manually, open tsconfig.json
and add "baseUrl": "./",
under compilerOptions
:
{
"compilerOptions": {
"baseUrl": "./",
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
That’s it! You’ve now completed setting up a new Next.js project with Tailwind and Storybook! If you have any trouble, you can check out this repo to see a completed Next.js Tailwind Storybook set up here:
Completed Next.js TypeScript Tailwind CSS Storybook Example Repo
If you found this article helpful, please feel free to heart this article!