Skip to content

[Bug] CSS ?url import broken with experimental.bundledDev — Tailwind v4 @import not processed and URL resolution is unstable #7488

@nikilok

Description

@nikilok

Which project does this relate to?

Start

Describe the bug

With experimental: { bundledDev: true } in Vite 8, the standard TanStack Start CSS pattern from the docs fails:

import appCss from '../styles.css?url'
// ...
links: [{ rel: 'stylesheet', href: appCss }]

The failure mode is not consistent — across reloads and version bumps I observed three distinct broken behaviors against the latest packages (react-start@1.168.13, start-plugin-core@1.171.6, start-server-core@1.169.4, react-router@1.170.8, vite@8.0.13, @tailwindcss/vite@4.3.0).

Mode A — hashed URL returns unprocessed source

?url resolves to /assets/styles-<hash>.css. The dev server returns 200 OK, but the body is essentially the raw source CSS — the Tailwind v4 plugin's transform never ran. Source src/styles.css is:

@import './fonts.css';
@import 'tailwindcss';
@import './transitions.css';

So the browser tries to fetch each of those at runtime:

URL Status Note
/assets/styles-crgemPDo.css 200 (9.3 kB) matches source file size, not the ~35 kB of expanded Tailwind
/<base>/fonts.css 404 unresolved CSS @import
/<base>/tailwindcss 404 Tailwind v4 bare-specifier resolution didn't run
/<base>/transitions.css 404 unresolved CSS @import

Mode B — relative URL

?url resolves to a bare relative string like "styles.css". The browser resolves it against the current page URL (e.g. /?search=foo) → /styles.css -> 404. The 16 kB body is Vite's HTML error page.

Mode C — source path

?url resolves to /src/styles.css (the path the unbundled-dev transform middleware would normally serve). In bundledDev that middleware is disabled, so → 404 with the same HTML error page body.

All three modes produce an unstyled page.

Complete minimal reproducer

nikilok/learn-tanstack-start#127

The PR enables experimental.bundledDev: true and demonstrates the working ?inline workaround. To reproduce this bug, undo the ?inline workaround:

  1. In apps/web/src/routes/__root.tsx, change import appCss from '../styles.css?inline' back to import appCss from '../styles.css?url'.
  2. Remove the inline <style dangerouslySetInnerHTML={{ __html: appCss }} /> tag from <head>.
  3. Add { rel: 'stylesheet', href: appCss } back into the route's head.links array.

Steps to Reproduce the Bug

  1. Check out the PR and apply the diff above.
  2. bun install and bun dev.
  3. Load the app in a browser.
  4. Observe in the Network tab: a styles*.css 404 and/or 404s for tailwindcss, fonts.css, transitions.css — page renders unstyled.

Expected behavior

?url should resolve to a URL whose response is the fully processed CSS (Tailwind expanded, @imports inlined), the way it does in vite build and the way ?inline does in dev. The pattern in the docs should work in bundledDev mode.

Screenshots or Videos

Browser Network tab in Mode A (all three CSS-pipeline failures visible simultaneously):

styles.css                            404   stylesheet   15.6 kB
styles.css?routes=__root__%2C%2F      200   stylesheet    0.6 kB   (dev-styles middleware, OK)
styles-crgemPDo.css                   200   stylesheet    9.3 kB   (unprocessed source!)
fonts.css                             404   stylesheet   15.6 kB
tailwindcss                           404   stylesheet   15.6 kB
transitions.css                       404   stylesheet   15.6 kB
Image

Platform

  • @tanstack/react-start: 1.168.13
  • @tanstack/start-plugin-core: 1.171.6
  • @tanstack/start-server-core: 1.169.4
  • @tanstack/react-router: 1.170.8
  • @tailwindcss/vite: 4.3.0
  • OS: macOS 26.5
  • Browser: Chrome (latest)
  • Bundler: Vite 8.0.13 with experimental.bundledDev: true
  • Bun: 1.3.13

Additional context

Workaround: use ?inline instead of ?url:

import appCss from '../styles.css?inline'
// ...
<style dangerouslySetInnerHTML={{ __html: appCss }} />

?inline forces the full Vite transform pipeline to run on the CSS (Tailwind expansion, @import resolution), and the processed CSS string is embedded directly into the JS bundle. Works in bundledDev, unbundled dev, and prod. Trade-offs: loses the natural <link rel="stylesheet"> semantic, and the bundled client JS grows by the CSS size (~35 kB for this app).

It's not obvious whether this is best fixed in TanStack Start's plugin pipeline, in @tailwindcss/vite, or in Vite core's ?url handling for bundledDev mode. Filing here because the failure surfaces against the Start-recommended pattern and Start users will hit it as they try bundledDev.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions