I veer away from CSS frameworks like Bootstrap because they result in sterilized designs. On a recent side project, I gave Tailwindcss a try and am now a believer. It strikes the perfect balance of design flexibility and rapid iteration.
Case in point: I rebuilt my Hugo theme, Henry, with Tailwind in three days1. I quite like how it’s turned out. Let me show you how to add it to a Hugo theme.
Approach
I like to keep things as simple as possible. So, it was important for me to use both Hugo & Tailwind as you would independently.
Two key differences in my approach:
- I don’t use Tailwind as a PostCSS plugin as much of the internet recommends.
- I keep the input css in my theme’s asset folder, but the compiled output css goes into the blog’s asset folder. This might seem like a curious choice, but it makes sense to me. People often add styling to pages in their blog folder that won’t reside in the theme. My own website doesn’t ship the index or landing page with my theme.
Installation
From your root hugo project directory:
# create a package.json file (with default options)
npm init -y
# install Tailwind CSS as a dependency
npm install -D tailwindcss
# create the tailwind.config.js config file
npx tailwindcss init
Now tell Tailwind what files to watch for changes:
// tailwind.config.js
module.exports = {
content: [
/* relevant files from the blog + theme */
"../../content/**/*.{html,md}",
"../../layouts/**/*.html",
/* relevant files from the theme */
"./layouts/**/*.html",
/* also pick nested css from theme */
"../../assets/css/*.css",
],
// ...
}
Add Tailwind to your blog.
/* blog-hugo/themes/henry/assets/css/input.css */
@import "fonts.css"; /* or other custom css you want */
@tailwind base;
@tailwind components;
@tailwind utilities;
That’s it! Fire up Tailwind and Hugo:
# start tailwind from the themes directory
npx tailwindcss \
-i themes/henry/assets/css/input.css \
-o ./assets/css/output.css \
--watch
# start hugo server from blog directory
hugo server
Bonus tip
Starting Tailwind and Hugo separately is a bore. Instead, I use a Procfile
and foreman to launch them both with one command2.
I prefer this approach over the traditional unix jobs
, bg
& fg
command foo because I can start everything in a single command. Additionally, I get color coded logs from each service simultaneously.
# Procfile.dev
css: npx tailwindcss -c ../../tailwind.config.js -i assets/css/input.css -o ../../assets/css/output.css --watch
hugo: cd ../.. && hugo server --buildDrafts
Install foreman and run:
brew install foreman
foreman start -f themes/henry/Procfile.dev
For my own website, I have a ./bin/dev
shell script 3 that checks if I have foreman and other tools installed and spins everything up in one shot.
Just use Henry
If you just want a solid Hugo theme that uses Tailwind and is easy to get up and running, just use Henry.
Revisions
- I changed the instructions to do the
npm install
of tailwind in my blog folder vs the theme. This allows me more flexibility in customizing via tailwind.