Skip to content

fix(html): keep stylesheet links inside <template> in place - #23982

Open
lumatic2 wants to merge 1 commit into
vitejs:mainfrom
lumatic2:fix/html-template-stylesheet-link
Open

lumatic2 wants to merge 1 commit into
vitejs:mainfrom
lumatic2:fix/html-template-stylesheet-link

Conversation

@lumatic2

@lumatic2 lumatic2 commented Nov 3, 2026

Copy link
Copy Markdown

fixes #23981

Since #17988, traverseNodes walks into <template> content, so a <link rel="stylesheet"> inside a template hits the same branch as a link in the document. In build the tag is removed and its CSS is bundled into the <head> stylesheet, so a declarative shadow DOM template loses its styles. Dev leaves the link as is.

This skips the CSS import for links inside a template. They go through processAssetUrl like links with media or disabled (#6748), so the href is rewritten and the tag stays in the template. The file is emitted as a plain asset, which means CSS plugins don't run on it and a small file gets inlined as a data: URL.

I added a <template shadowrootmode="open"> with a stylesheet link to the assets playground. The tests check the color inside the shadow root and that the built HTML keeps the link in the template. Both fail without the fix.

I used Claude Code to trace the code path and draft the change and tests. I reviewed it myself: I read the link branch in html.ts and ran the new tests with and without the fix.

fixes vitejs#23981

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

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.

<link rel="stylesheet"> inside <template shadowrootmode> is moved to a global stylesheet in build

1 participant