1

I'm using Tailwind CSS v4 and I'd like to generate separate compiled CSS files for different sections of my app (e.g. blog.css, dashboard.css), each one containing only the utility classes used in that section.

In TailwindCSS v3, this was possible via the --content CLI flag. This flag seems to be removed in v4.

Is there a clean way in v4 to split the build per section with custom content sources, without ending up with one global CSS file?

2
  • 1
    By the way, if you're trying to speed up the download with this, you might not achieve your goal, as it's simpler to download your entire CSS once rather than downloading the CSS for your 126 pages 126 times, especially when 50-60% of it is the same. Commented Mar 26 at 9:03
  • If the content of your different pages is in separate files, you have the option to disable automatic source detection and run the Tailwind CLI manually as many times as you have files. You can also write a script using PostCSS to automate the process without using the CLI. Commented Mar 26 at 9:04

1 Answer 1

0

Where did the content setting, which was common in v3, go?

Starting from v4, automatic source detection has been introduced. This has deprecated the content value in the tailwind.config.js and the --content flag in the CLI. Automatic source detection scans all files and looks for all class names used in the project. By default, it skips paths listed in .gitignore. It is possible to customize this using CSS-first, allowing you to add extra external paths (or paths ignored by .gitignore but still needed). However, you can also completely disable this feature and specify certain sources instead.

How to customize TailwindCSS's sources from v4

The @source directive can be used to attach additional sources to be processed by TailwindCSS.

@import "tailwindcss";

@source "../node_modules/@my-company/ui-lib";

When importing TailwindCSS, you have the option to disable automatic source detection:

@import "tailwindcss" source(none);

@source "../src";
@source "../shared";

Alternatively, you can declare the first source by default instead of using none, like this:

@import "tailwindcss" source("../src");
 
@source "../shared";

Solution with CLI

In v4, the --content flag has been deprecated, as you mentioned. Instead, there is no alternative, just the solutions described above. So, you need to declare the source or sources in the CSS in advance.

Solution with PostCSS

However, in the case of a script, you have the option to customize the CSS before using it. This way, for each run, you can set the --content flag equivalent @source, but in this case, you no longer need the CLI, just PostCSS.

I quickly put together an automated PostCSS JS script. You can run it with Node, and it will generate the appropriate CSS file from the declared sources.

This way, you only need to declare the necessary settings once for your entire project, but the JS script will create a separate CSS file for each route, containing only the classes used on that specific route.

Requirements
npm install tailwindcss @tailwindcss/postcss postcss
How to use
node ./generate-css-files.js

generate-css-files.js

import fs from 'fs'
import path from 'path'
import postcss from 'postcss'
import tailwindcssPlugin from '@tailwindcss/postcss'

const sourceDir = './src'
const outputDir = './dist'

const sources = [
  // can declare directory or file path

  // include ./src/aboutus/**/*.* such as ./src/aboutus/index.html
  // target: ./dist/aboutus.css
  'aboutus',
  
  // include only ./src/contact.html
  // target: ./dist/target.html
  'contact.html',
]

// Can declare TailwindCSS's style.css content directly
const styleCSS = `
  @import "tailwindcss" source(none);

  @theme {
    /* ... */
  }
`
// Alternative can use style.css by readFile
// - In this case please use @import "tailwindcss" source(none); in your CSS file
// const styleCSS = fs.readFileSync('./src/style.css', 'utf8')

for (const source of sources) {
  const sourcePath = `${sourceDir}/${source}`
  const sourceName = path.basename(source, path.extname(source))

  // Convert Tailwind CSS to native CSS
  postcss([
    tailwindcssPlugin(),
  ])
    // here can declare TailwindCSS's style.css directly
    .process(`
      ${styleCSS}

      @source "${sourcePath}";
    `, { from: sourceDir })

    // Write the generated CSS to a file
    .then((result) => {     
      const output = `${outputDir}/${sourceName}.css`
      fs.writeFileSync(output, result.css, 'utf8')
      console.log(`${output} generated for ${source}`)
    })
    .catch((err) => console.error('An error occurred:', err))
}
Expected result

Scan all files in the ./src/aboutus directory and output the used classes into ./dist/aboutus.css.

Scan only the ./src/contact.html file and output the used classes into ./dist/contact.css.

Extra

Of course, you can expand this in any way you like. The sources can also be an object, where you specify the target CSS path as the key, and then list the paths to be used in the given CSS in an array (which will check which CSS classes you've used). This way, you can merge multiple different paths into a single CSS file, e.g., ./src/aboutus.html and ./node_modules/mypackage.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.