-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Description
Describe the bug
We've migrated a sizeable code base to the Svelte 5 compiler, while some components still use the legacy Svelte 4 syntax.
We've found a regression regarding the server side rendering of Svelte 4 components when css: 'injected'
is used.
Reproduction
Please see:
https://github.com/molily/svelte-server-test
Two components:
SvelteTestComp.svelte:
<script>
import Child from './Child.svelte';
let hello = 'hello';
</script>
<p>SvelteTestComp.svelte</p>
<Child bind:hello />
<style>
* {
border: 2px solid red;
padding: 1em;
}
</style>
Note the bind:hello
!
Child.svelte:
<script>
/** @type {string} */
export let hello;
</script>
<p>Child.svelte hello: {hello}</p>
<style>
* {
border: 2px solid blue;
padding: 1em;
}
</style>
SSR code in node build-server.js
:
import { render } from 'svelte/server';
import SvelteTestComp from './SvelteTestComp.svelte';
const { head, body } = render(SvelteTestComp, { props: {} });
console.log('body', body);
console.log('head', head);
build-server.js creates a SSR build with esbuild-svelte.
node build-server.js
The output is written to dist/
, it's already in the repo:
This output looks perfectly fine to me. The styles of both components are in the code:
var $$css = {
hash: "svelte-t13rfg",
code: ".svelte-t13rfg {border:2px solid blue;padding:1em;}"
};
function Child($$payload, $$props) {
$$payload.css.add($$css);
// SvelteTestComp.svelte
var $$css2 = {
hash: "svelte-1d6hxxn",
code: ".svelte-1d6hxxn {border:2px solid red;padding:1em;}"
};
function SvelteTestComp($$payload) {
$$payload.css.add($$css2);
So I assume the problem is not in esbuild-svelte.
Now, render SvelteTestComp using the bundle:
node dist/svelte-render-server.js
Output:
body <!--[--><p class="svelte-1d6hxxn">SvelteTestComp.svelte</p> <p class="svelte-t13rfg">Child.svelte hello: hello</p><!----><!--]-->
head <style id="svelte-1d6hxxn">.svelte-1d6hxxn {border:2px solid red;padding:1em;}</style>
Note the missing <style>
for Child
(with the blue border).
What's causing this problem? We've managed to trace it back to bind:hello
. 🤯
Either remove it or change it to a non-binding prop passing {hello}
, make a build, run the build.
Output without bind
:
body <!--[--><p class="svelte-1d6hxxn">SvelteTestComp.svelte</p> <p class="svelte-t13rfg">Child.svelte hello: hello</p><!----><!--]-->
head <style id="svelte-1d6hxxn">.svelte-1d6hxxn {border:2px solid red;padding:1em;}</style><style id="svelte-t13rfg">.svelte-t13rfg {border:2px solid blue;padding:1em;}</style>
This is what I'm expecting in the bind:hello
case as well. Am I missing anything?
Thanks a lot for looking into this. Much appreciated.
System Info
Binaries:
Node: 23.9.0 - ~/.n/bin/node
npm: 11.2.0 - ~/.n/bin/npm
npmPackages:
svelte: 5.23.2
esbuild: 0.25.1
esbuild-svelte: 0.9.2
Severity
annoyance