Last week I was assigned the task of configuring a project that uses Svelte, Tailwindcss, and Storybook. I had never worked with any of the tech, so I spent a good amount of time researching. What I've come to realize is that there's not a lot of articles that break down how to work with them, and the ones that are available don't use the latest Tailwind or Storybook. I decided to write this article to show how you can use Svelte with the recently updated Storybook and Tailwindcss. I will break it down step by step to make sure it's easy to follow, especially for someone who's new to these frameworks like I was a few weeks ago.
To better explain how the dependencies work together, I'm going to divide the article into 2 main parts. We'll set up Svelte first, then move on to Storybook. Let's get started!
Part 1: Svelte
(If you don't have a Svelte app yet, follow
this tutorial.)
Step 1: Install Tailwind and dependencies
For the main app, we need to install 3 main dependencies.
npm i tailwindcss postcss-import svelte-preprocess
- tailwindcss: this is the official Tailwindcss plugin
- svelte-preprocess: we need this for Svelte components' styles
- postcss-import: to import css files that use Tailwindcss syntax into our svelte components
To use these dependencies, we need to update their configuration files: postcss, rollup, and tailwind.
Step 2: Configuration
It's time for the fun part! There are 3 main configuration files that we need to edit: postcss.config.js
, rollup.config.js
, and tailwind.config.js
Let's start by creating the file postcss.config.js
at our root directory. To use Tailwindcss, we need to add the tailwindcss
plugin to our postcss configuration. We also need to add postcss-import
, so that any Tailwindcss syntax can be directly imported to svelte components.
// postcss.config.js
module.exports = {
plugins: [require("postcss-import"), require("tailwindcss")],
};
The next step is to tackle the rollup config. In our rollup.config.js
, we need to set up svelte-preprocess
to process our component styles with the above postcss configuration.
// rollup.config.js
export default {
...
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
preprocess: sveltePreprocess({ postcss: true }),
css: (css) => {
css.write("bundle.css");
},
}),
...
Finally, we need to set up our tailwind config by creating a tailwind.config.js
at the root directory. You can do this quickly by using the command: npx tailwind init
.
3 main things we need to configure:
-
purge
: This will ensure that all the unused CSS rules that Tailwind creates will be purged at build. -
defaultextractor
: a more customized extractor to make sure that we don't lose tailwind styles used in class directive. -
whitelist
: to indicate which selectors are safe to leave in the final CSS.
Your config should now look like this:
// tailwind.config.js
const production = !process.env.ROLLUP_WATCH;
module.exports = {
future: {},
purge: {
content: ["./src/**/*.svelte", "./src/**/*.html"],
enabled: production, // disable purge in dev
options: {
whitelist: [/svelte-/],
/* eslint-disable no-unused-vars */
defaultExtractor: (content) =>
[...content.matchAll(/(?:class:)*([\w\d-/:%.]+)/gm)].map(
([_match, group, ..._rest]) => group
),
},
},
theme: {
extend: {},
},
variants: {},
plugins: [],
};
Step 3: Add global Tailwindcss to your app
Now let's add some Tailwind styling to your app. Before you start adding any custom styles, let's add the global utilities packages first. Create a css file with the below content.
/* globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
if you want to use these global styles in a svelte component for hot reloading, you can import the css file like this.
// Tailwindcss.svelte
<style global>
@import "globals.css";
</style>
The reason why we want to keep our global styles in a css file is because we need it for storybook later.
Part 2: Storybook:
Step 1: Install Storybook.
Follow this guide for the complete installation: https://storybook.js.org/docs/svelte/get-started/install
Step 2: Add svelte-preprocess
Now we need to add a preprocessor to Storybook so that our stories will render Svelte properly. We do this by adding webpack configuration to .storybook/main.js
const sveltePreprocess = require("svelte-preprocess");
module.exports = {
stories: ["../stories/**/*.stories.js"],
addons: ["@storybook/addon-knobs"],
webpackFinal: async (config) => {
const svelteLoader = config.module.rules.find(
(r) => r.loader && r.loader.includes("svelte-loader")
);
svelteLoader.options = {
...svelteLoader.options,
preprocess: sveltePreprocess({ postcss: true }),
};
return config;
},
};
Step 3: Import global styles to storybook
Lastly, It's time to import your global styles to storybook, and we can do it easily by importing the global.css file we created earlier. Now you see why we want our global styles to be in a css file, rather than Svelte.
@import "globals.css";
Aaaaand that's it! You should be able to use Tailwindcss with Svelte and Storybook effortlessly now. I hope this was helpful, feel free to comment below if you spot any errors. Happy coding!
Top comments (5)
Hello there, Great article!
Anyways, for anyone that is having an issue with your
postcss-import
issue or any PostCSS 8 compatibility issue that would look like this on the error:At the time of writing this (Which is March 14, 2021), Here's what you need to do:
npx sb@next init --type svelte
instead ofnpx sb init --svelte
This is because the StoryBook developer has updated the dependency issue in their pre-release branch.sb@next
, press [ Enter ]Here's a GitHub issue for this problem:
github.com/storybookjs/storybook/i...
To future proof this for StoryBook 7:
npm i -D @storybook/addon-postcss
oryarn install -D @storybook/addon-postcss
@storybook/addon-postcss
inside the main.js.Awesome article! Other guides were out of date and didn't get things working, but I was able to get up and running mainly because of your writeup.
In addition to the instructions above, this is what I had to do to get things running:
PostCSS 8 issues (At the time of writing 9 Jan 2021)
I had to use the compatibilty build for Tailwind:
yarn remove tailwindcss postcss autoprefixer
yarn add -D tailwindcss@npm:@tailwindcss/postcss7-compat @tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
In
package.json
, I also had to change from"postcss-import": "^14"
to"postcss-import": "^12"
for the same reason.Other notes
yarn add autoprefixer
fornpx tailwind init
to worknpx -p @storybook/cli sb init --type svelte
svelte-preprocess
rather thansvelte-preprocessor
Hi @JayLiu,
Thanks for your info. I struggled to get it to work and your comment, helped alot.
Thanks again!.
Ryan
Hi Linh thx for the article. I don't get where u import the globals.css to storybook. Would u mind explain? Greets!
You should put into preview .cjs/js, right below the other imports.
I hope it helps.
// .storybook/preview.cjs
import '../static/base-style.css';
export const parameters ={
..
}