Resolving Tailwind CSS Styles Not Loading in Production Next.js Builds

Tailwind CSS is an excellent framework for building responsive user interfaces, but developers sometimes notice a puzzling issue: styles that load perfectly during development (npm run dev) are missing or broken in production builds (npm run build). This happens because Tailwind's optimization step purges unused styles during compilation, and if your configuration files do not map to the exact folder paths containing your React components, the compiler accidentally purges required styles. This guide explains how to fix this issue.
1. How Tailwind Purging Works in Next.js
Tailwind CSS scans your files for class names to generate only the CSS that you actually use. It does not parse JavaScript logic; it uses regular expressions to find complete class name strings. If your component directory path is missing from your tailwind.config.js file, the class names inside those components are marked as unused and removed from the final CSS output.
Consider this problematic configuration file where the src/components directory is omitted:
// tailwind.config.js - Problematic
module.exports = {
content: [
'./pages/**/*.{js,ts,jsx,tsx}', // Scans pages, but misses source subdirectories!
],
theme: {
extend: {},
},
plugins: [],
}
2. The Fix: Correcting tailwind.config.js Content Paths
To prevent styles from being purged, ensure that your configuration scans all folders that contain components, pages, or layout files. Below is the standard setup for a modern Next.js project using the src/ directory:
// tailwind.config.js - Optimized
module.exports = {
content: [
'./src/pages/**/*.{js,ts,jsx,tsx}',
'./src/components/**/*.{js,ts,jsx,tsx}',
'./src/app/**/*.{js,ts,jsx,tsx}',
],
theme: {
extend: {},
},
plugins: [],
}
3. Avoiding Dynamic Class Construction
Because Tailwind scans source code statically, constructing class names dynamically (e.g. string concatenation) will prevent Tailwind from detecting them, and the styles will not be generated in the production build.
// Problematic - Tailwind cannot detect this dynamic class!
const buttonColor = 'red';
return <button className={`bg-${buttonColor}-500`}>Submit</button>;
// Optimized - Write complete class name strings
const buttonClass = isError ? 'bg-red-500' : 'bg-blue-500';
return <button className={buttonClass}>Submit</button>;
4. Conclusion
Whenever you update configuration paths, run a production build locally with npm run build && npm run start to verify that all layout components, responsive configurations, and custom utility classes load properly before publishing changes to your users.