From ee1249b43cb702d1ea97274ba7849fb8153bd4e2 Mon Sep 17 00:00:00 2001 From: Nathan Asdarjian Date: Thu, 20 Aug 2026 03:02:07 -0700 Subject: [PATCH] fix: preserve renderer type in copy() during SSR (#18616) Fixes #18404 `` 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 `` instead of ``. 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) --- .changeset/hydration-head-renderer-type.md | 5 +++++ packages/svelte/src/internal/server/renderer.js | 1 + .../head-with-multiple-binding-components/Foo.svelte | 3 +++ .../Wrapper.svelte | 6 ++++++ .../_expected.html | 0 .../_expected_head.html | 4 ++++ .../main.svelte | 12 ++++++++++++ 7 files changed, 31 insertions(+) create mode 100644 .changeset/hydration-head-renderer-type.md create mode 100644 packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/Foo.svelte create mode 100644 packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/Wrapper.svelte create mode 100644 packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/_expected.html create mode 100644 packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/_expected_head.html create mode 100644 packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/main.svelte diff --git a/.changeset/hydration-head-renderer-type.md b/.changeset/hydration-head-renderer-type.md new file mode 100644 index 0000000000..bc566c158d --- /dev/null +++ b/.changeset/hydration-head-renderer-type.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: don't corrupt renderer type during SSR's legacy `bind:` retry loop diff --git a/packages/svelte/src/internal/server/renderer.js b/packages/svelte/src/internal/server/renderer.js index 35aac64721..ba6a361a90 100644 --- a/packages/svelte/src/internal/server/renderer.js +++ b/packages/svelte/src/internal/server/renderer.js @@ -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; diff --git a/packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/Foo.svelte b/packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/Foo.svelte new file mode 100644 index 0000000000..b991cdf968 --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/Foo.svelte @@ -0,0 +1,3 @@ + diff --git a/packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/Wrapper.svelte b/packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/Wrapper.svelte new file mode 100644 index 0000000000..d48c90fe59 --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/Wrapper.svelte @@ -0,0 +1,6 @@ + + + diff --git a/packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/_expected.html b/packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/_expected.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/_expected_head.html b/packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/_expected_head.html new file mode 100644 index 0000000000..904fa1d9eb --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/_expected_head.html @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/main.svelte b/packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/main.svelte new file mode 100644 index 0000000000..b68ccd07fe --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/head-with-multiple-binding-components/main.svelte @@ -0,0 +1,12 @@ + + + + + + + + + +