-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
fix: use client CSS for inlineStyleThreshold to include conditionally rendered components #15147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: use client CSS for inlineStyleThreshold to include conditionally rendered components #15147
Conversation
… rendered components
Server builds tree-shake CSS for components inside conditional blocks (e.g., {#if})
that aren't rendered during SSR. This caused styles to be missing when those
components were later rendered client-side.
The fix uses client CSS content directly (which includes all component styles)
and rewrites relative url() references to absolute paths for proper asset loading.
Fixes #13878
🦋 Changeset detectedLatest commit: 600928d The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
The server bundle is no longer needed since we now use client CSS content directly for inlining, rather than mapping client to server stylesheets.
|
@teemingc What do you think of this? I picked this one as a pesky, hard-to-diagnose bug to test OpenCode / Opus 4.5 with. AFAICT it works (the test fails on |
|
You're right about both downsides to this approach. As an alternative, I was trying to figure out how/why Vite bundles the CSS for each page because I can see that vite-plugin-svelte emits the CSS for each Svelte component individually for both client and server builds. I was hoping and looking for a way to tell Vite to emit all CSS from components in that page for the server output. |
|
I guess that solution would have half of the issues of the above, right? As in, we'd still potentially ship "more" CSS than necessary (basically purposefully disabling some level of treeshaking) but we'd avoid having to hackily rewrite URLs? |
|
Actually, treeshaking would still work as intended. It’s only suppose to happen for dynamically imported components anyway. There’s two ways to go about this:
|
Summary
Fixes #13878 - CSS styles for conditionally-rendered components are not applied when
inlineStyleThreshold > 0in production builds (regression since v2.21.3).Problem
When
inlineStyleThresholdis set, SvelteKit inlines CSS below the threshold into the HTML. The previous implementation (from #13723) used server CSS content for inlining, but server builds tree-shake CSS for components that aren't rendered during SSR (e.g., components inside{#if}blocks where the condition is initially false).This caused styles to be missing when those components were later rendered client-side, because:
Solution
Use client CSS content directly instead of mapping client CSS files to server CSS files. The client build includes CSS for all components in the dependency tree, including conditionally-rendered ones.
To handle asset URLs (fonts, images) that use relative paths in client CSS, the fix rewrites
url()references to absolute paths using the configured assets base path.This approach is simpler than the previous implementation - we no longer need the
server_bundleparameter that was added in #13723, since we're not doing any client-to-server CSS mapping anymore.Changes
build_server.js: Use client CSS content directly with URL rewriting, remove server bundle dependencyindex.js: Stop passing server bundle tobuild_server_nodesanalyse.js: Update call site to match new signatureinlineStyleThresholdTesting
inlineStyleThresholdtests pass