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.