vitejs / vitejs/vite-plugin-react

CSS precedence ordering between serverResources and clientReferenceDeps is non-deterministic during SSR

Open
#1,100 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

pending triage plugin: rsc
Dominant language
TypeScript
Stars
1.2k
Forks
269
Avg merge
1d 3h
Merged PRs (30d)
19

Description

Related plugins
Describe the bug

Description

When a server component imports CSS and client components also import CSS that shares the same output file, the <link> tag ordering in SSR output is non-deterministic on the first request. The order between serverResources CSS (data-precedence="vite-rsc/importer-resources") and clientReferenceDeps CSS (data-precedence="vite-rsc/client-reference") is inconsistent. On subsequent requests, they appear in the correct order.

This causes style conflicts when both CSS sources contain rules for the same selectors with different values, since the cascade depends on source order.

Reproduction

https://github.com/user-attachments/assets/4429981f-4b8d-4967-9cf1-16ded0942d87

Repository: https://github.com/iamchanii/vite-plugin-rsc-test

Observed Behavior

The CSS load order is non-deterministic:

  • Incorrect order (observed on initial load): position is static (entry.css overrides index.css)
  • Correct order (observed after refresh): position is absolute (index.css loads first)

Note: The incorrect order can appear randomly, not just on the first request.

Inspecting <head>

First request:

<link rel="stylesheet" href="/assets/entry-xxx.css" data-precedence="vite-rsc/client-reference">
<link rel="stylesheet" href="/assets/index-xxx.css" data-precedence="vite-rsc/importer-resources">

Subsequent requests (correct order):

<link rel="stylesheet" href="/assets/index-xxx.css" data-precedence="vite-rsc/importer-resources">
<link rel="stylesheet" href="/assets/entry-xxx.css" data-precedence="vite-rsc/client-reference">

Possible Fix

I've opened a draft PR at https://github.com/vitejs/vite-plugin-react/pull/1099 with a minimal fix:

Proposed solution:
In preloadDeps(), ensure server resources CSS (importer-resources precedence) is registered before client reference CSS (client-reference precedence). This ensures index.css loads before entry.css consistently, maintaining the correct cascade order regardless of timing.

Happy to iterate on the approach if there's a better way to handle this.

Reproduction

https://github.com/iamchanii/vite-plugin-rsc-test

Steps to reproduce
bun install
bun run build && bun run start
  1. Open http://localhost:3000 — check the position value displayed
  2. Refresh the page — check the position value again
System Info
System:
    OS: macOS 26.2
    CPU: (11) arm64 Apple M3 Pro
    Memory: 157.41 MB / 36.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 24.4.1 - /Users/ette/.local/share/mise/installs/node/24.4.1/bin/node
    Yarn: 1.22.21 - /Users/ette/.local/share/mise/installs/node/24.4.1/bin/yarn
    npm: 11.4.2 - /Users/ette/.local/share/mise/installs/node/24.4.1/bin/npm
    pnpm: 8.14.3 - /Users/ette/.local/share/mise/installs/node/24.4.1/bin/pnpm
    bun: 1.3.5 - /Users/ette/.local/share/mise/installs/bun/1.3.5/bin/bun
  Browsers:
    Chrome: 144.0.7559.133
    Edge: 144.0.3719.115
    Safari: 26.2
    Safari Technology Preview: 18.4
  npmPackages:
    @vitejs/plugin-react: latest => 5.1.3 
    @vitejs/plugin-rsc: latest => 0.5.19 
    vite: ^7.3.1 => 7.3.1
Used Package Manager

bun

Logs

No response

Validations

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in the plugin-rsc preloadDeps() path and use the linked reproduction repository; run bun install, then bun run build && bun run start. Inspect the SSR head on the first request and after refresh, focusing on the ordering of serverResources and clientReferenceDeps CSS links. Done means the importer-resources link consistently precedes the client-reference link and the reported cascade result is stable.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.