Skip to main content

Getting Tailwind to work with Eleventy

I was so frustrated with Tailwind and Eleventy, because I wanted to get it working, and it just didn't! I couldn't understand why.

My steps to get Tailwind to work

I followed Thirus's Youtube tutorial for this.

  1. Install Eleventy normally.
  2. Install tailwindcss, postcss and autoprefixer with the command npm install -D tailwindcss postcss autoprefixer.
    • Because I was using a framework like Eleventy, I had to use postcss and autoprefixer.
  3. Create config files for tailwindcss and postcss:

tailwindcss:

/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./public/**/*.{html,js}"],
theme: {
extend: {},
},
plugins: [],
};

(I'm not sure if the content should really be from the /public/ folder, but let it be for now. It works!)

postcss:

module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
  1. Include Tailwind's components in the css file:
@tailwind base;
@tailwind components;
@tailwind utilities;
  1. Reference the stylesheet as usual in the layout file and add tailwind.config.js as a watch target to .eleventy.js:
eleventyConfig.addWatchTarget("tailwind.config.js");
  1. (Now is the important step!) Get Tailwind running in the terminal. The problem for me was that I didn't understand how to get Eleventy and Tailwind to run at the same time. Thirus showed in the video that it's possible by opening two terminals... 🙃 Which I didn't even realize was possible... So, run Eleventy with npm start (or whatever is in your package.json) and open a second terminal and run npx tailwindcss -i ./src/styles/style.css -o ./public/styles/style.css --watch.
    • Notice that the -i means the input file, so use yours! Also -o means output file.
    • Also note that your layout file should reference that output file!

And that got it working for me.

It took such a long time... Now I can actually get started with my project.

Problems didn't end there

I couldn't run npx @11ty/eleventy --serve and npx tailwindcss -i ./src/styles/style.css -o ./public/styles/style.css --watch at the same time to do proper development, so I had to figure it out.

I found out two ways!

  1. Use Git Bash and run "npx tailwindcss -i ./src/styles/style.css -o ./public/styles/style.css --watch && npx @11ty/eleventy --serve". The order is paramount! It didn't work with running Eleventy first.
  2. I installed Concurrently (npm) and used the command "dev": "concurrently \"npx tailwindcss -i ./src/styles/style.css -o ./public/styles/style.css --watch\" \"npx @11ty/eleventy --serve\"". Here the order is also important.

Bugs that persisted

I wanted to run them concurrently, because Tailwind would sometimes break. Hopefully this fixes that.

It didn't, but I fixed it later.

I fixed it!

Problem was that I was using npx tailwindcss -i ./src/styles/style.css -o ./public/styles/style.css --watch thus outputting the CSS straight to public. This made it so that Eleventy was building the site content first and then outputting it to public, which didn't have the CSS file at first.

I fixed it by changing it to npx tailwindcss -i ./src/styles/style.css -o ./src/styles/tailwind.css --watch. I named it "tailwind.css", so it wouldn't override the setup CSS file. This way Tailwind builds the CSS file and Eleventy then builds uses that in the output.

This also meant changing the stylesheet linking in my base.njk layout: <link rel="stylesheet" href="./styles/tailwind.css" />.

I also added the new addWatchTargets, so Eleventy checks for the CSS changes:

eleventyConfig.addWatchTarget("./public/**/*/*.css");
eleventyConfig.addWatchTarget("./src/**/*/*.css");

Now the persisting problem is that these watch targets seem to cause lots of rebuilding. I have to look into that too...

Further modifications

I figured that the rebuiding issue stems from overlapping watch commands, so I streamlined what's in my .eleventy.js:

eleventyConfig.addPassthroughCopy("./src/**/*/tailwind.css");
eleventyConfig.addPassthroughCopy("./src/images/**/*.{png, jpeg}");

eleventyConfig.addWatchTarget("./src/**/*/tailwind.css");
eleventyConfig.addWatchTarget("tailwind.config.js");

Now it watches directly the outputted tailwind.css and I figure Eleventy takes care of the building. It seems to work for now.

It did cause some of rebuilding being dropped of off BrowserSync, but it still builds it properly.