Tailwind, Blazor and Sisyphus

💡
Ah. The pitfalls of AI.

Turns out everywhere I turned I was getting instructions for installing Tailwind v3 and not v4. But Tailwind itself was installing v4.

And in some cases, AI was comingling the instructions. That accounts for nonsense that follows.

If you want an updated and, likely, correct set of instructions, go here.

This might be the most painful experience I've had in a while. At the end of the day, there were just an unimaginable number of opaque, undocumented instructions that led to enormous amounts of wasted time.

What resulted is a trial-and-error, half-assed, kinda-working, sorry-excuse for configuration of any product in 2025.

90% of these problems come from unfamiliarity with Tailwind, Node and other pretty important parts. But I imagine that's pretty typical for a junior Blazor developer.

I'm almost certain there's a better way to do this. I sure couldn't figure it out - and that's on me. It would sure be great if Tailwind or anyone else brought the docs up to date.

Steps to create a dotnet 9 Blazor Interactive Auto app that uses Tailwind:

  1. Create the project
dotnet new blazor -n <your-project-name-here> -ai -e -int Auto -au Individual

This will yield a solution with two projects.

💡
All of the following steps take place in the server project.
  1. In the Properties folder, edit the launchSettings.json file and add the following lines to the profile sections marked http and https.
"hotReloadEnabled": true ,
"watchStaticFiles": true,
  1. In the wwwroot folder empty out the app.css file and replace the contents with these lines:
@import "tailwindcss";
@tailwind utilities;
  1. In the project root folder, create a tailwind.config.js file with these lines:
/** @type {import('tailwindcss').Config} */
module.exports = {
    content: [
        "./**/*.{razor,html,cshtml}",
    ],
    theme: {
        extend: {},
    },
    plugins: [],
}
  1. Still in the project root, create a postcss.config.js file with these lines:
module.exports = {
    plugins: {
        tailwindcss: {},
        autoprefixer: {},
    }
}
  1. Edit the App.razor file, removing the CSS directives and replace it with the one below. This means all styling will come from the file that was processed by Tailwind:
<link rel="stylesheet" href="@Assets["app.min.css"]" />
  1. Open a terminal app in the server project root and enter this command to install tailwind/cli globally:
npm install -g tailwindcss @tailwindcss/cli
  1. Then enter this command to install the other node nonsense needed:
npm install tailwindcss @tailwindcss/cli postcss autoprefixer postcss-cli
  1. Still in the root of the project type this:
npx tailwindcss -i wwwroot/app.css -o wwwroot/app.min.css --watch
  1. Open another terminal window in the server project root and type this:
dotnet watch

At this point, you should be able to use tailwind commands in the server project and have them reflected in the web page that got launched. That said - there's no IntelliSense.

💡
If you run the project, you'll notice that using a tailwind class in a razor page in the client project will not be reflected in the updated app.min.css. And that's because we're not scanning for it.

If you use that class in the server project, then the npx processor picks it up, adds it to app.min.css and it suddenly becomes available to the client project and it works.
💡
As hard as I tried to get tailwind.config to respect the content line and scan the client project (not shown here), it simply would not do it. I have no idea why.

A workaround exists for using classes only in the client project. If you change the following lines in the head section of App.razor:

    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="@Assets["app.min.css"]" />

You get to play around with tailwind. That said, in Tailwind v4, they suggest another command and it didn't work for me (and others).

Hot reload is a little hit or miss with this in place, and there's still no Intellisense.

Good luck.