26.7 Avoiding the npm Dependency: Dart Sass Embedded

Right, so you want to build a Hugo site with SCSS and Tailwind, but the thought of wrestling with a sprawling node_modules directory and a fragile package.json makes you twitch. I get it. You came to Hugo for its simplicity and speed, not to recreate the frontend plumbing of a Fortune 500 company’s web app. The good news is, Hugo’s got your back. It has a brilliant, built-in secret weapon for processing your SCSS without ever needing to type npm install: the Dart Sass Embedded protocol.

26.6 Dark Mode with Tailwind and Hugo

Right, dark mode. It’s 2024, and we’re still pretending this is a fancy new feature. Let’s be honest: your users want it, your retinas need it, and implementing it in a static site generator like Hugo with Tailwind CSS is actually a joy once you stop fighting the tools and start letting them do the work for you. The core idea is simple: we toggle a class (usually .dark) on a root element like <html> or <body>, and Tailwind’s dark: variant does the rest, swapping your color utilities based on that class. The real trick, the part that separates a pro setup from a hacky one, is how you handle the user’s preference, persist their choice, and avoid that awful flash of un-styled content (FOUC) on load.

26.5 Purging Unused Tailwind Classes with content Paths

Right, let’s talk about the single most important, and frankly, most annoying, part of using Tailwind with Hugo: purging. You’ve fallen in love with Tailwind’s utility-first speed, but if you just ship the entire 4MB+ of the development build to your users, you’re a monster. A well-intentioned monster, but a monster nonetheless. The purge option in Tailwind is our salvation, our robot vacuum that goes around and only picks up the classes we’ve actually used. But you have to tell it where to look, and with Hugo, that’s a bit of a dance.

26.4 Setting Up Tailwind CSS with Hugo

Right, let’s get our hands dirty. You’re about to make Hugo and Tailwind play nice together, which is a fantastic idea. You get the component-driven, content-focused power of Hugo and the rapid, utility-first styling of Tailwind. But their default setups are like two brilliant people who speak different languages; we need to build a solid interpreter between them. We’re going to process your Tailwind CSS on the fly, as part of Hugo’s build process. This is the way.

26.3 PostCSS Pipeline: postcss.config.js and npm Integration

Right, so you’ve decided to build a Hugo site and you want to use Tailwind CSS. Smart. You’ve probably hit the first roadblock: Hugo’s built-in SASS/SCSS support is great, but it’s a completely separate universe from the Node.js-based tooling Tailwind requires. You can’t just @import "tailwindcss"; and call it a day. This is where we stop fighting the tool and start making it work for us. We’re going to set up a PostCSS pipeline. Think of it as a bouncer for your CSS: every line of your stylesheet has to get past PostCSS and its friends before it’s allowed into the final, built site.

26.2 SCSS Variables, Nesting, Mixins, and Imports

Alright, let’s get our hands dirty. You’re using Hugo, which means you’re already a step ahead of the game because Hugo’s built-in Sass/SCSS compilation is fantastic. It means we can write clean, powerful, and, most importantly, DRY (Don’t Repeat Yourself) stylesheets and let Hugo handle the messy conversion to plain CSS for the browser. This is where SCSS becomes your best friend, and Tailwind is the quirky, super-efficient roommate who keeps things interesting.

26.1 SCSS Compilation with Hugo Extended: toCSS

Right, let’s talk about getting Hugo to turn your elegant SCSS into the blunt, browser-ready CSS it so desperately needs. This isn’t magic, it’s Hugo’s toCSS pipeline, and it’s the single most important reason you need the “Extended” version of Hugo. The regular version is a brilliant static site generator; the Extended version is that plus a full-fledged asset pipeline. Don’t even try this with the regular version. You’ll just get errors and a profound sense of disappointment, and I won’t feel bad for you.

— joke —

...