I'm setting up a new project using Next.js (v15.3.0 - Pages Router) and Tailwind CSS (v4.1.4) and I've hit a persistent build issue where Tailwind utility classes are not being recognized.
The Core Problem:
The Next.js development server (next dev
) fails to compile, throwing errors like:
Error: Cannot apply unknown utility class: bg-gray-50
Initially, this happened for default Tailwind classes (bg-gray-50
) used with @apply
in my globals.css
. After trying different configurations in globals.css
(like using @import "tailwindcss/preflight"; @reference "tailwindcss/theme.css";
), the error shifted to my custom theme colors:
Error: Cannot apply unknown utility class: text-primary-600
When trying to use the theme()
function directly in @layer base
, I get:
Error: Could not resolve value for theme function: theme(colors.gray.50).
Essentially, it seems the PostCSS/Tailwind build process isn't recognizing or applying any Tailwind utility classes correctly within the CSS build pipeline.
Relevant Versions:
@tailwindcss/postcss
: 4.1.4Configuration Files:
tailwind.config.js
(Simplified attempt):
const defaultTheme = require('tailwindcss/defaultTheme');
const colors = require('tailwindcss/colors');
module.exports = {
content: [
"./src/pages/**/*.{js,ts,jsx,tsx}",
"./src/components/**/*.{js,ts,jsx,tsx}",
],
theme: { // No 'extend'
fontFamily: {
sans: ['Inter', ...defaultTheme.fontFamily.sans],
},
colors: {
transparent: 'transparent',
current: 'currentColor',
black: colors.black,
white: colors.white,
gray: colors.gray, // Explicitly included
red: colors.red,
green: colors.green,
primary: { // My custom color
DEFAULT: '#2563EB',
// ... other shades 50-950
600: '#2563EB',
700: '#1D4ED8',
},
secondary: { /* ... custom secondary color ... */ },
},
ringOffsetColor: {
DEFAULT: '#ffffff',
},
},
plugins: [],
};
postcss.config.js
:
module.exports = {
plugins: {
"@tailwindcss/postcss": {}, // Using the v4 specific plugin
autoprefixer: {},
},
};
src/styles/globals.css
(Latest attempt):
/* src/styles/globals.css */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');
@import "tailwindcss/preflight";
@tailwind theme;
@tailwind utilities;
@layer base {
html {
font-family: 'Inter', sans-serif;
scroll-behavior: smooth;
}
body {
@apply bg-gray-50 text-gray-900 antialiased;
}
a {
@apply text-primary-600 hover:text-primary-700 transition-colors duration-150;
}
}
Troubleshooting Steps Attempted (Without Success):
.next
, node_modules
, package-lock.json
and re-ran npm install
.content
paths in tailwind.config.js
and baseUrl
in tsconfig.json
.tailwind.config.js
: Tried removing theme.extend
, defining colors directly under theme
.gray: colors.gray
, red: colors.red
etc. to the config.globals.css
Directives:
@tailwind base; @tailwind components; @tailwind utilities;
.@import "tailwindcss/preflight"; @reference "tailwindcss/theme.css"; @tailwind utilities;
(this fixed default class errors but not custom ones when using @apply
).@import "tailwindcss/preflight"; @tailwind theme; @tailwind utilities;
(current).@apply
vs. theme()
: Tried using each of these methods within @layer base
in globals.css
. @apply
failed first, then theme()
too.postcss.config.js
Variations: Tried using tailwindcss: {}
instead of @tailwindcss/postcss: {}
.Despite these steps, the build consistently fails, unable to recognize or process Tailwind utility classes referenced in CSS (especially within globals.css
). Standard utility classes used directly on JSX elements (e.g., <div className="p-4 bg-primary-500">
) also fail to apply styles correctly because the underlying CSS isn't generated properly.
Has anyone encountered similar issues with this specific stack (Next.js 15 / Tailwind 4 / Pages Router)? What could be causing this fundamental breakdown in Tailwind's processing within the Next.js build? Any configuration nuances I might be missing?
Thanks in advance for any insights!
Since TailwindCSS v4, TailwindCSS needs to be imported differently. Due to incorrect import, your classes didn't exist, so you couldn't use them. This is how it should look correctly:
@import "tailwindcss";
@layer base {
html {
font-family: 'Inter', sans-serif;
scroll-behavior: smooth;
}
body {
@apply bg-gray-50 text-gray-900 antialiased;
}
a {
@apply text-primary-600 hover:text-primary-700 transition-colors duration-150;
}
}
In addition, starting from v4, the default usage of tailwind.config.js
has been discontinued. The file itself is no longer necessary, as a CSS-first configuration has been introduced. You can read more about it here:
There have indeed been many breaking changes that even AI models haven't fully kept up with. It's worth going through the StackOverflow and TailwindCSS resources regarding this. A lot of guides, videos, and documentation created for TailwindCSS v3 have become outdated in v4.
tailwind.config.js
@theme
directive - TailwindCSS v4 Docs@import "tailwindcss";
@theme {
/* Font families */
--font-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
/* Colors */
--color-transparent: transparent;
--color-current: currentColor;
/* There's no need to declare black, white, gray, red, or green — they're included in TailwindCSS by default */
/* Primary color */
--color-primary-600: #2563EB;
--color-primary-700: #1D4ED8;
--color-primary: #2563EB;
/* Secondary color */
--color-secondary: #FACC15; /* Example: yellow-400, adjust to your desired value */
/* Ring offset */
--ring-offset-color: #ffffff;
}
@layer base {
html {
font-family: 'Inter', sans-serif;
scroll-behavior: smooth;
}
body {
@apply bg-gray-50 text-gray-900 antialiased;
}
a {
@apply text-primary-600 hover:text-primary-700 transition-colors duration-150;
}
}
Related:
There's no need to declare default colors - as you did in your tailwind.config.js
- unless you want to override them. If you're fine with the default values, you don't need to declare anything.
If you want to remove a default color (e.g., green
), you can do so like this:
--color-green-*: initial;
This will remove utilities like text-green-500
, etc.
However, note that text-green-500
and similar classes aren't included in the compiled CSS unless you actually use them in your code - so removing them manually often isn't necessary.