Skip to content

fix(rsc): import resources for each loadCss(id) in a module - #1508

Open
k35o wants to merge 2 commits into
vitejs:mainfrom
k35o:fix-rsc-load-css-multiple-ids
Open

k35o wants to merge 2 commits into
vitejs:mainfrom
k35o:fix-rsc-load-css-multiple-ids

Conversation

@k35o

@k35o k35o commented Oct 14, 2026

Copy link
Copy Markdown

Description

In a build, only the first import.meta.viteRsc.loadCss(id) in a module gets its __vite_rsc_importer_resources_<hash> import. A second call with a different id references an identifier that was never declared, and the render fails with a ReferenceError:

export function Root() {
  return (
    <html lang="en">
      <head>
        {import.meta.viteRsc.loadCss('./a.tsx')}
        {import.meta.viteRsc.loadCss('./b.tsx')}
      </head>
      ...
ReferenceError: __vite_rsc_importer_resources_<hash of b> is not defined

#742 added a guard so that two calls with the same id in one module do not import the same binding twice. The guard is a single importAdded flag for the whole module, so after the first import it also skips the imports for every other id. This PR tracks the added imports per hash instead. vite dev is not affected, because it imports each call's resources dynamically.

We ran into this in a framework that generates a route table and renders loadCss(<route file>) for each lazily loaded route, so that a page links only the CSS of its own route chunk.

The new manual-css-multiple-ids e2e test renders two components whose CSS is loaded only through two loadCss(id) calls in one module, with rscCssTransform: false. Without the fix, its build case fails because the page does not render. With the fix, it passes in dev and build.

A separate commit fixes the existing manual-css test. examples/starter-extra calls rsc() without options, so s.replace('rsc({', ...) changed nothing, and the test ran with automatic CSS injection. With rsc() replaced, rscCssTransform: false takes effect, and the test still passes in dev and build.

pnpm -C packages/plugin-rsc test --run (525 tests) and pnpm -C packages/plugin-rsc tsc pass. e2e/manual-css.test.ts passes in Chromium. Four tests in e2e/starter.test.ts fail on my machine (macOS), and they fail the same way on main without this change.

k35o added 2 commits October 14, 2026 15:27
starter-extra calls `rsc()` without options, so replacing `rsc({` was a no-op and the test still ran with automatic CSS injection.
Only the first `import.meta.viteRsc.loadCss(id)` in a module got its `__vite_rsc_importer_resources_<hash>` import in build, since one flag tracked whether any import had been added. A second call with a different id then referenced an undeclared identifier and failed at render with a ReferenceError. Track the added imports per hash instead.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant