Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tailwind classes from client:only components are not included in final builds #13139

Closed
1 task
davepeck opened this issue Feb 4, 2025 · 9 comments
Closed
1 task
Labels
- P2: has workaround Bug, but has workaround (priority) ecosystem: upstream Upstream package has issue needs response Issue needs response from OP

Comments

@davepeck
Copy link

davepeck commented Feb 4, 2025

Astro Info

Astro                    v5.2.5
Node                     v22.13.1
System                   macOS (arm64)
Package Manager          npm
Output                   static
Adapter                  none
Integrations             @astrojs/react

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

A simple astro 5.2 / tailwind 4 / framework UI project.

There's a single index.astro page, which includes a react component in BlueBox.tsx via <BlueBox client:only />.

The tailwind CSS classes from BlueBox are culled correctly when using npm run dev; however, the final build output from npm run build does not contain those classes. Culling CSS classes should still be a build-time concern, even for client:only components.

I'm using the latest tailwind integration (astro add tailwind) as described in the 5.2 announcement. I'm using React for the framework UI component, but I wouldn't be surprised if this reproduces with other frameworks, too.

Dev builds work as expected:

  1. npm run dev
  2. visit http://localhost:4321/
  3. see a square box with a blue background

Full builds do not:

  1. npm run build
  2. run a simple HTTP server over the dist/ directory (I use python -m http.server 8000 --directory dist/)
  3. visit http://localhost:8000/
  4. see no square box with no blue background

Looking at the CSS generated in the full build pass, definitions are missing for the bg-blue-200, h-64 and w-64 classes used by the BlueBox component.

Image: npm run dev results

Image

Image: npm run build results

Image

What's the expected result?

The expected CSS classes are included in the output of npm run build; build and dev should look the same.

Link to Minimal Reproducible Example

https://github.com/literalgarage/astro-tailwind-bug (GitHub repo)

https://stackblitz.com/github/literalgarage/astro-tailwind-bug

Participation

  • I am willing to submit a pull request for this issue.
@github-actions github-actions bot added the needs triage Issue needs to be triaged label Feb 4, 2025
@florian-lefebvre florian-lefebvre added ecosystem: upstream Upstream package has issue - P4: important Violate documented behavior or significantly impacts performance (priority) and removed needs triage Issue needs to be triaged labels Feb 6, 2025
@florian-lefebvre florian-lefebvre marked this as a duplicate of #13144 Feb 6, 2025
@drecdroid
Copy link

What solves for me with SolidJS is to import the global style in any of the components that is used with the client:only directive. You don't need to put that in every component but I do so just in case I forget to import in any of them a receive a big surprise later.

This doesn't solve for css modules loaded from a component that has been used with the client:only directive. Not with @import nor with @reference, or using relative or aliased import. It has worked some times but others don't, perhaps a cache issue. Will look further.

What would be great is to be able to set the global style in the Vite plugin itself so you don't need to load it in any other place. For example:

import { defineConfig } from "astro/config";

import solidJs from "@astrojs/solid-js";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  integrations: [solidJs()],
  vite: {
    plugins: [tailwindcss({
      globalStyle: "./src/styles/global.css"
    )],
  },
});

@bittere
Copy link

bittere commented Feb 9, 2025

Was having the same issue without any framework, just Astro and some Typescript with Tailwind.

This appears to also have been raised in the TailwindCSS repository:
tailwindlabs/tailwindcss#15794

Specifically, this comment seems to have solved it (at least for me):
tailwindlabs/tailwindcss#15794 (comment)

@davepeck
Copy link
Author

davepeck commented Feb 10, 2025

An update here: while this bug was labeled "ecosystem: upstream", it's clear from comments by the tailwind team that this isn't simply an issue with their own tooling:

...we're actively looking into this issue but that's not something we can fix easily from the Vite plugin itself.

They describe a workaround for now:

It's currently necessary to manually mark client-only components as dependencies via the @source directive.

They've opened a discussion with the Astro team to figure out how to tackle this.

@jesus997
Copy link

I encountered a similar issue with Vue. In my project, I import the CSS file (which includes Tailwind's directives) in my ./src/layouts/Layout.astro file. This works perfectly for Astro components, but the Vue components don't have their classes included in the final build.

After some digging through various issues on both the Astro and TailwindCSS repositories, I found a workaround to use the TailwindCSS configuration from version 3.x in version 4. Initially, I solved it by adding the directive:

./src/styles/global.css:

@import "tailwindcss";
@config "../../tailwind.config.js";

This approach works, but while reviewing the Tailwind documentation, I discovered a better method that doesn’t require a JS file. Instead, you can simply add this directive to your CSS file:

./src/styles/global.css:

@import "tailwindcss" source("../src");

This magically fixes the issue. It seems that the problem is related to how TailwindCSS 4 detects the source files. In my case, since the CSS file (that imports Tailwind) is located in ./src/styles, Tailwind defaults to using that directory as the base path. By specifying the source parameter with ../src, Tailwind starts detecting all the files correctly.

I reached this conclusion after reading the TailwindCSS documentation on detecting classes in source files. If my interpretation is off, please let me know so I can better understand the root cause.

I hope this solution helps others facing a similar issue!

@florian-lefebvre florian-lefebvre added - P2: has workaround Bug, but has workaround (priority) and removed - P4: important Violate documented behavior or significantly impacts performance (priority) labels Feb 21, 2025
@florian-lefebvre
Copy link
Member

Yes using a source directive works in the meantime

@florian-lefebvre
Copy link
Member

This should be fixed by Tailwind 4.0.8, can you guys test it out?

@florian-lefebvre florian-lefebvre added the needs response Issue needs response from OP label Feb 21, 2025
@jesus997
Copy link

This should be fixed by Tailwind 4.0.8, can you guys test it out?

Yep, this seems to be working well now :D

@florian-lefebvre
Copy link
Member

I'll wait for another confirmation before closing

@spiffytech
Copy link

LGTM!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
- P2: has workaround Bug, but has workaround (priority) ecosystem: upstream Upstream package has issue needs response Issue needs response from OP
Projects
None yet
Development

No branches or pull requests

6 participants