Setting up Tailwind CSS ("Tailwind") in Next.JS 9.3.0 ("Next").
This is based on
- the official setup example.
- Sung's blog entry, Tailwind for Create-React-App Cheat Sheet
- Assumption
- Install DEV dependencies
- Create a Tailwind configuration file
- Configure PostCSS for Tailwind
- Create a Tailwind file
- Create NPM Scripts
- Import Tailwind CSS Output
- (Optional) Normalize
body
I will assume that you have an existing Next site.
# yarn
yarn add -D @fullhuman/postcss-purgecss autoprefixer npm-run-all cross-env cssnano postcss-cli purgecss tailwindcss
# npm
npm install -D @fullhuman/postcss-purgecss autoprefixer npm-run-all cross-env cssnano postcss-cli purgecss tailwindcss
npx tailwind init tailwind.config.js
- Create a PostCSS configuration file.
# bash
touch postcss.config.js
# Powershell
new-item postcss.config.js
- Configure PostCSS
If you have React components in <project root>/components
folder, add "./components/**/*.js"
to contents: [...]
.
⚠ Note: Next disallows require in PostCSS configuration file.
So unlike the create-react-app version, you need to use a subset of configuration option using an object syntax.
const purgecss = {
'@fullhuman/postcss-purgecss': {
// Use this if you have `./components` folder
// content: ["./components/**/*.js", "./pages/**/*.js"],
content: ['./pages/**/*.js'],
defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || []
}
}
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
// Purge and minify CSS only production builds only
...(process.env.NODE_ENV === 'production'
? { ...purgecss, cssnano: {} }
: {})
}
}
Create a file ./src/styles/tailwind.css
.
# bash
mkdir -p ./src/styles/ && touch ./src/styles/tailwind.css
# Powershell
new-item ./src/styles/tailwind.css -ItemType File -Force
and add following Tailwind utilities.
@tailwind base;
@tailwind components;
@tailwind utilities;
Update the `package.json` script to create Tailwind CSS file before starting/building.
"scripts": {
"build:css": "postcss src/styles/tailwind.css -o src/styles/index.css",
"watch:css": "postcss src/styles/tailwind.css -o src/styles/index.css --watch",
"env:dev": "cross-env NODE_ENV=development",
"env:prod": "cross-env NODE_ENV=production",
"next:dev": "sleep 5 && next dev",
"next:build": "next build",
"dev": "run-p env:dev watch:css next:dev",
"build": "run-s env:prod build:css next:build",
"start": "next start"
},
If you already don't have a Custom App, create it (./pages/_app.js
).
Import the Tailwind generated CSS file.
import React from 'react'
// This is the Tailwind generated CSS file
import '../src/styles/index.css'
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
}
I couldn't figure out how but for some reason, Tailwind's normalize in @tailwind base
isn't applied thus applying margin (8px
) around the site.
You can add normalize CSS as a global style in the custom App file.
The updated App
file would look like the following.
import React from 'react'
import '../src/styles/index.css'
export default function App({ Component, pageProps }) {
return (
<>
<Component {...pageProps} />
{/*
Tailwind's normalize isn't applied
thus 8px margin is added around "body".
Fix it with a global style.
https://github.com/zeit/next.js/issues/151#issuecomment-257090939 */}
<style jsx global>{`
body {
margin: 0;
padding: 0;
box-sizing: border-box;
}
`}</style>
</>
)
}