fix: preserve renderer type in copy() during SSR (#18616)

Fixes #18404

`<svelte:head>` combined with two or more components that each use `bind:` on a child component's prop corrupts a renderer's `.type` during SSR, misplacing the head hydration marker in `<body>` instead of `<head>`.

Reason: `copy()` (`packages/svelte/src/internal/server/renderer.js`) rebuilds via `new Renderer(this.global, this.#parent)`. That constructor defaults `.type` from the *parent's* current type, not from `this.type`. To fix it we therefore reassign it (like already do for the boundary elsewhere)
pull/18537/merge
Nathan Asdarjian 5 days ago committed by GitHub
parent 9c2494b134
commit ee1249b43c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: don't corrupt renderer type during SSR's legacy `bind:` retry loop

@ -451,6 +451,7 @@ export class Renderer {
*/
copy() {
const copy = new Renderer(this.global, this.#parent);
copy.type = this.type;
copy.#out = this.#out.map((item) => (item instanceof Renderer ? item.copy() : item));
copy.promise = this.promise;
return copy;

@ -0,0 +1,6 @@
<script>
import Foo from './Foo.svelte';
let bar = $state();
</script>
<Foo bind:bar />

@ -0,0 +1,4 @@
<!--ssr:0-->
<link rel="canonical" href="/test">
<meta name="description" content="test">
<!--ssr:0-->

@ -0,0 +1,12 @@
<script>
import Wrapper from './Wrapper.svelte';
</script>
<svelte:head>
<link rel="canonical" href="/test" />
<meta name="description" content="test" />
</svelte:head>
<Wrapper />
<Wrapper />
<Wrapper />
Loading…
Cancel
Save