Tailwindcss not working with Next.js: fix the config
A Next.js build that finishes clean but ships a page with zero Tailwind styling almost always has one wrong setting: the paths Tailwind scans for class names.
TL;DR#
If next build finishes with no error but the page renders with zero Tailwind
styling (or just the body/heading resets), the usual cause is a content array
in tailwind.config.js that does not match the files holding your className
strings — not a broken PostCSS pipeline. Point content at every folder that
actually contains your components, delete the stale .next cache, and make
sure your CSS file is imported exactly once, in the root layout.
This is the failure mode behind a 213,000-view Stack Overflow question, "Tailwindcss not working with next.js; what is wrong with the configuration?" — reproduced below on Tailwind CSS 3.4.19 and Next.js 14.2.5.
warn - No utility classes were detected in your source files. If this is unexpected, double-check the `content` option in your Tailwind CSS configuration.
warn - https://tailwindcss.com/docs/content-configuration
✓ Compiled successfullyWhy it happens#
Tailwind does not ship a stylesheet with every possible class pre-built. Its
own documentation describes the mechanism plainly: it "works by scanning all
of your HTML files, JavaScript components, and any other templates for class
names, generating the corresponding styles and then writing them to a static
CSS file" (Tailwind CSS docs, Installing with PostCSS).
If a file is outside the globs Tailwind scans, every className inside it is
invisible to the compiler — next build has no way to know those strings were
ever meant to become CSS, so it does not treat it as an error. The build
compiles, the page renders, and the only thing missing is the styling.
Reproduced in a throwaway Next.js 14.2.5 + Tailwind CSS 3.4.19 App Router
project, 8 October 2026: with tailwind.config.js pointing content at
./src/**/*.{js,ts,jsx,tsx,mdx} while every component actually lived under
./app, the build printed the warning above and the compiled stylesheet under
.next/static/css/ contained only Tailwind's Preflight reset — no
.text-3xl rule at all. Changing nothing else but the glob to
./app/**/*.{js,ts,jsx,tsx,mdx} and rebuilding made the warning disappear and
put the .text-3xl rule back in the output. One setting, same files, same
command — that is the entire bug.
The highest-voted answer on the source question (score 121) names the same cause
for the App Router layout specifically: a tailwind.config.js generated for
the old pages/ directory, or copied from a tutorial, that never lists
./app/**/*.{js,ts,jsx,tsx,mdx}.
A second, independent cause on the same question (score 104) is a stale
.next build cache: Next.js caches compiled CSS and JS output between runs,
so after a config change that should fix the styling, an old cached build can
still ship the pre-fix stylesheet until the cache is cleared.
Fix#
1. Confirm which Tailwind major you are actually running — the fix is different for each one.
npm ls tailwindcss2. On Tailwind CSS v3, point content at every folder that holds a
className. For the Next.js App Router:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}',
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {},
},
plugins: [],
}If your project still uses the pre-v3 purge key instead of content
(the config in the source question does), it is not the problem by itself:
Tailwind 3.4.19 normalises purge into content with a deprecation warning,
not silently. Rename the key for clarity, but the glob pattern is what has to
be correct either way.
3. Delete the Next.js build cache after any content/config change, then rebuild:
rm -rf .next
npm run dev4. Make sure the Tailwind directives are imported exactly once, in the root
layout (app/layout.js / app/layout.tsx), not re-declared in a page or a
component:
import './globals.css'
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}@tailwind base;
@tailwind components;
@tailwind utilities;Next.js's own install guide for Tailwind v3 uses this exact three-directive
globals.css imported from the root layout
(Next.js docs, Tailwind CSS v3).
If a project instead imports fonts or other @import rules above the
directives in the same file, keep @tailwind base/components/utilities as
the first rules in the file — some PostCSS setups fail or reorder output when
an @import for an external URL comes first. On the Pages Router there is no root layout: the stylesheet belongs in pages/_app.js, and importing it from a component instead triggers the Pages Router Global CSS import error.
Verify the fix#
After rebuilding, check the compiled output directly instead of trusting the page visually (a cached browser tab can hide a real fix, and a dev-server hot-reload can hide a real break):
grep -rl "text-3xl" .next/static/css/A match means the utility class made it into the stylesheet. No match, with a
clean build and no warning, means content still is not scanning the file
that uses the class — check the exact path again, including the file
extension list.
One email a month — the latest explained errors
What the site published that month — mostly Next.js, Supabase and Node errors, explained. You confirm by email; unsubscribe any time in one click.
Which Tailwind major are you actually on?#
The source question is from 2020 and its tailwind.config.js uses purge
and future.removeDeprecatedGapUtilities, both v3-era settings. A plain
npm install tailwindcss today installs Tailwind CSS v4, whose PostCSS setup
has no content array at all: install tailwindcss and @tailwindcss/postcss,
add @tailwindcss/postcss to postcss.config.mjs, and @import "tailwindcss";
in the CSS file (Tailwind CSS docs, Installing with PostCSS).
If classes are missing on v4, the content-array fix above does not apply —
check the PostCSS plugin name instead, covered in
Fix: Tailwind PostCSS Plugin Has Moved (Vite + React).
Two further v4-only failure modes to rule out before touching content:
- A fresh
npm installwith no version pin ontailwindcsssilently resolves v4 instead of the v3 the project was built against, and a v3-erapostcss.config.jsstops working the moment v4 lands — covered in Fix "Missing specifier" & npx tailwindcss init Errors. - A v4 project using shadcn/ui-style config tokens (
border-borderand similar) needs itstailwind.config.jsloaded explicitly with@config, because v4 no longer loads it automatically — see Fix "Cannot apply unknown utility class border-border".
Next error to expect#
Fixing the content globs resolves classes that are missing everywhere. If
instead only some classes are missing — commonly ones built from a dynamic
string like `text-${color}-500` — the cause is different: Tailwind's
scanner needs the complete class name as a literal string somewhere in the
file, so a template literal that only exists at runtime never gets detected.
That is a separate bug from a wrong content path and needs the class names
written out literally (for example in a lookup object), not a change to the
glob. If the font-family class is present on the element but a custom font still renders as the default, the @font-face rule is what failed, and the Tailwind custom font @font-face fix covers the invalid format('ttf') hint and the nested quotes that stop the family name from matching.
A build that compiles without the warning above, but whose styles still don't
match in production while they work in next dev, is usually a different
problem again: a style that depends on a dynamic class name surviving minification,
not a scanning gap. Treat it as a separate investigation rather than assuming
the same content fix applies.
Further reading: Fix: TypeError: Invalid PostCSS Plugin found at: plugins[0].
Frequently Asked Questions
Still stuck? Paste your error.
Paste the error message or stack trace — we check it against every fix and tool on the site.
Continue Reading
Fix "Cannot apply unknown utility class border-border"
Reproduced on Tailwind 4.1.4 to 4.3.3 and 3.4.19: the four wordings of this error, the @config path that resolves, the hsl() trap in @theme, and the two v3 causes.
Fix: TypeError: Invalid PostCSS Plugin found at: plugins[0]
A postcss.config.js that lists plugin names as plain strings compiles nothing — the array syntax needs each entry already resolved, not a package name.
Fix "Missing specifier" & npx tailwindcss init Errors
Why a clean npm install turns a working Vite + Tailwind build into three errors at once, reproduced one at a time with the fix for each.


