Skip to content

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

@iamchanii

Description

@iamchanii

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. serverResources CSS (data-precedence="vite-rsc/importer-resources") may not appear at all — only clientReferenceDeps CSS (data-precedence="vite-rsc/client-reference") is rendered. On subsequent requests, both precedence groups 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

2026-02-07.00.44.49.mov

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

Observed Behavior

  • First request: position is static (wrong — entry.css overrides index.css)
  • After refresh: position is absolute (correct)

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 #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

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions