Est. reading time: 6 minutes

NextJS and TailwindCSS - a great match ❤️

If you've read my introductory post you know that I wanted to try out TailwindCSS in a side project for a while now. I figured this page here would be the perfect chance to do exactly that. So I got into the docs and looked up how exactly one does that.

Let's make use of that tailwind

TailwindCSS, the brainchild of Adam Wathan, is an "an open-source utility-first CSS framework for rapidly building custom user interfaces". That means it gives you a couple (a lot actually) predefined classes you can use instead of writing custom CSS. Let me show you an example, taken from this page here:

const H1 = (props: any) => (
<h1 className="py-8 text-5xl font-bold" {...props}>
{props.children}
</h1>
);

You see that the className property of the H1 component has some weird values like py-8, text-5xl or font-bold. These are Tailwinds predefined utility classes which are then used to apply some styles. py-8 is a shortcut and does nothing more than add some padding on the top and bottom (y-axis). text-5xl defines the font-size and font-bold, well, declares the font-weight as 700 (bold).

The great thing about this is, it actually enforces a consistent design system on you without even trying. If you ever worked on a code base with heavy CSS use, you know how hard it is to maintain constraints and not litter custom values everywhere. At least that's a problem I'm having 🤷‍♂️

If you want to find out more about why TailwindCSS is really worth trying out, head over to their site. They have introduced a playground recently as well, so the entry barrier is as low as it gets.

So how do I hook it up to Next?

For this next bit, I assume you already have a NextJS project up and running. If not simply use one of their starters. This guide should work regardless of wether you start a brand new project or want to include Tailwind into an existing code base.

First you gonna need to install some required packages. I'm going to use npm here because I never hopped onto the yarn train 😅

# This works for NextJS version 10+
npm install tailwindcss@latest postcss@latest autoprefixer@latest

So what is all this? Well, tailwindcss should be pretty self-explanatory I think. Since Tailwinds is basically just a PostCSS plugin you need to install that as well. PostCSS is just "a tool for transforming CSS with JavaScript". autoprefixer is another great PostCSS plugin which parses the CSS and adds some vendor prefixes (like -webkit or -moz) to the rules to enable maximum browser compatibility.

Once you're done with that it's time to create some config files. Use npx tailwindcss init -p to create a minimal tailwind.config.js file. It should also create a complete postcss.config.js file which should contain everything you need. For reference here's what should be in them:

// tailwind.config.js
module.exports = {
// NOTE: add this to tree-shake (purge) unused styles in production builds
// if you have more folders (e.g. /components) just add them to the list
purge: ['./pages/**/*.js'],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
};
// postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

One config to rule them all

Since NextJS is also using PostCSS we need to make sure that the default configuration used by them does not get overridden by ours. To this end Next specifies that...

When you define a custom PostCSS configuration file, Next.js completely disables the default behavior. Be sure to manually configure all the features you need compiled, including Autoprefixer. You also need to install any plugins included in your custom configuration manually, i.e. npm install postcss-flexbugs-fixes postcss-preset-env.

So we're going to do exactly that.

npm install postcss-flexbugs-fixes postcss-preset-env

After that simply plug them in into your postcss.config.js. The config that NextJS is using can be found directly in their docs.

// modified postcss.config.js
module.exports = {
plugins: {
'postcss-flexbugs-fixes': {},
'postcss-preset-env': {
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
features: {
'custom-properties': false,
},
},
tailwindcss: {},
autoprefixer: {},
},
};

Final step to include Tailwind in your CSS

Now you have 2 options - if you don't want or need any custom CSS and are fine with all the neat things that Tailwind gives you, you can include it directly in your JS, like so:

// pages/_app.js
import 'tailwindcss/tailwind.css';
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;

You should also remove other custom CSS files like globals.css and make sure that they are not referenced anywhere. Important to note is that you can customize TailwindCSS however you want using the tailwind.config.js file. Option 1 only means you don't have extra CSS files lying around.

Option 2 is for you if you still want to have some custom CSS files. In this case you go to your globals.css file (which NextJS generates for you automatically - if not, just add it like shown here) and use the @tailwind directive to include Tailwind's base, components, and utilities styles like so:

/* globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

As a final step in this case you have to make sure that the globals.css file is imported in your _app.js component.

// pages/_app.js
import '../styles/globals.css';
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;

Job's done

That's it. If you run next dev now you should be good to go 🙂 If you had trouble at any step, just ping me on Twitter or head over to the (amazing) TailwindCSS and/or NextJS docs.