[🐞] Error with TailwindCSS 4 when used in Qwik
Which component is affected?
Qwik Rollup / Vite plugin
Describe the bug
I'm experimenting with TailwindCSS version 4, but there's an issue when it's used with Qwik. I created an issue in the TailwindCSS repository, but it seems that the problem originates from the Qwik Vite plugin (that's what the issue comments suggest).
TailwindCSS Issue: tailwindlabs/tailwindcss#13112
Reproduction
https://codesandbox.io/p/devbox/loving-glade-zdpd88?file=%2Fsrc%2Froutes%2Findex.tsx
Steps to reproduce
No response
System Info
System:
OS: macOS 14.3.1
CPU: (8) arm64 Apple M2
Memory: 571.66 MB / 16.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 21.6.1 - ~/.nvm/versions/node/v21.6.1/bin/node
npm: 10.2.4 - ~/.nvm/versions/node/v21.6.1/bin/npm
pnpm: 8.15.4 - /opt/homebrew/bin/pnpm
bun: 1.0.30 - /opt/homebrew/bin/bun
Browsers:
Chrome: 122.0.6261.111
Edge: 122.0.2365.63
Safari: 17.3.1
npmPackages:
@builder.io/qwik: 1.5.1 => 1.5.1
@builder.io/qwik-city: 1.5.1 => 1.5.1
undici: 6.7.0 => 6.7.0
vite: 5.1.5 => 5.1.5
Additional Information
No response
conversation from the other thread
So from this answer there is a space for improvement. From their response this is the piece of code to improve https://github.com/BuilderIO/qwik/blob/c88e53d49dc65020899d770338f4e51f3134611e/packages%2Fqwik%2Fsrc%2Foptimizer%2Fsrc%2Fplugins%2Fvite-server.ts#L102-L126
Tailwind v3
Tailwind v4
@import "tailwindcss"; inside global.css triggers our code to add that links in the <head>
For those interested in continuing to explore TailwindCSS version 4 without encountering this problem, I have shared a temporary and provisional solution in this comment https://github.com/tailwindlabs/tailwindcss/issues/13112#issuecomment-1983444305
Is there any news about this? It should be noted that this problem only happens in dev mode, when the build is done for production, the error disappears.
Tailwind v4 it's in alpha now
any PRs/solutions are welcome
Please note that the issue is Qwik is overriding styles in an @layer. For example, let's say you have a tailwind v4 configuration like this:
@import "tailwindcss";
@layer base {
a {
@apply text-blue-500;
}
}
@theme {
--color-monza-50: #fff1f2;
--color-monza-100: #ffdfe2;
--color-monza-200: #ffc4c9;
--color-monza-300: #ff9ba3;
--color-monza-400: #ff626f;
--color-monza-500: #ff3142;
--color-monza-600: #f01225;
--color-monza-700: #bb0a19;
--color-monza-800: #a70d1a;
--color-monza-900: #8a121c;
--color-monza-950: #4b040a;
}
The a tag will never make the text blue, because Qwik is overriding this in the vite plugin. Same with other things, such as items in the @theme
Just to understand, everything is working fine in production?
So we only need to be more careful in dev mode?
Just to understand, everything is working fine in production?
So we only need to be more careful in dev mode?
correct
Perhaps we can fix this by having the qwikvite plugin figure out which file is importing the css and only adding it to the page if it's a .js file
I can see in a Qwik Astro app everything just works because we aren't using Qwik's dev server. (devSsrServer: false)
Astro (or possibly Vite) seems to have a script tag in the head that points to the css file
https://github.com/withastro/astro/blob/22eafffd100ee2839d5a08b20d553c7f11e400c9/packages/astro/src/vite-plugin-astro-server/css.ts
This looks to me like their approach
Similar to what you mentioned, this seems to fix it @wmertens
for (const [file, modules] of allModules) {
console.log('Checking file:', file);
for (const mod of modules) {
console.log('Checking module:', mod.url);
if (mod.url.endsWith('.css')) {
console.log('Found CSS:', mod.url);
const importers = Array.from(mod.importers);
const hasJsImporter = importers.some((importer) => {
const importerPath = importer.url || importer.file;
return (
importerPath &&
(importerPath.endsWith('.js') ||
importerPath.endsWith('.ts') ||
importerPath.endsWith('.tsx') ||
importerPath.endsWith('.jsx'))
);
});
if (hasJsImporter) {
manifest.injections!.push({
tag: 'link',
location: 'head',
attributes: {
rel: 'stylesheet',
href: `${base}${mod.url.slice(1)}`,
},
});
}
}
}
}
🙌 woohoo @thejackshelton , let's get this into a PR 👌