diff --git a/.changeset/short-chicken-compare.md b/.changeset/short-chicken-compare.md new file mode 100644 index 000000000000..d0f6c22de4b7 --- /dev/null +++ b/.changeset/short-chicken-compare.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure last empty text node correctly hydrates diff --git a/packages/svelte/src/internal/client/dom/operations.js b/packages/svelte/src/internal/client/dom/operations.js index 6dfce9ebd320..627bf917eee1 100644 --- a/packages/svelte/src/internal/client/dom/operations.js +++ b/packages/svelte/src/internal/client/dom/operations.js @@ -154,8 +154,10 @@ export function first_child(fragment, is_text) { */ export function sibling(node, count = 1, is_text = false) { let next_sibling = hydrating ? hydrate_node : node; + var last_sibling; while (count--) { + last_sibling = next_sibling; next_sibling = /** @type {TemplateNode} */ (get_next_sibling(next_sibling)); } @@ -163,13 +165,20 @@ export function sibling(node, count = 1, is_text = false) { return next_sibling; } - var type = next_sibling.nodeType; + var type = next_sibling?.nodeType; // if a sibling {expression} is empty during SSR, there might be no // text node to hydrate — we must therefore create one if (is_text && type !== 3) { var text = create_text(); - next_sibling?.before(text); + // If the next sibling is `null` and we're handling text then it's because + // the SSR content was empty for the text, so we need to generate a new text + // node and insert it after the last sibling + if (next_sibling === null) { + last_sibling?.after(text); + } else { + next_sibling.before(text); + } set_hydrate_node(text); return text; } diff --git a/packages/svelte/tests/hydration/samples/text-empty-2/_config.js b/packages/svelte/tests/hydration/samples/text-empty-2/_config.js new file mode 100644 index 000000000000..f47bee71df87 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/text-empty-2/_config.js @@ -0,0 +1,3 @@ +import { test } from '../../test'; + +export default test({}); diff --git a/packages/svelte/tests/hydration/samples/text-empty-2/_expected.html b/packages/svelte/tests/hydration/samples/text-empty-2/_expected.html new file mode 100644 index 000000000000..ff12f10bfb75 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/text-empty-2/_expected.html @@ -0,0 +1 @@ + diff --git a/packages/svelte/tests/hydration/samples/text-empty-2/main.svelte b/packages/svelte/tests/hydration/samples/text-empty-2/main.svelte new file mode 100644 index 000000000000..ae1ed05e3a84 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/text-empty-2/main.svelte @@ -0,0 +1,7 @@ + + + + {name}{remaining >= 2 ? ',' : ''} +