From 6657490351fe12f9f1991c6fdb8fa7bf3b0dfb3b Mon Sep 17 00:00:00 2001 From: Miner Date: Thu, 29 Jan 2026 16:02:04 +0100 Subject: [PATCH] fix: merge consecutive text nodes during hydration for large text content Fixes #17582 Browsers automatically split text nodes exceeding 65536 characters into multiple consecutive text nodes during HTML parsing. This causes hydration mismatches when Svelte expects a single text node. The fix merges consecutive text nodes during hydration by: - Detecting when the current node is a text node - Finding all consecutive text node siblings - Merging their content into the first text node - Removing the extra text nodes This restores correct hydration behavior for large text content. --- .../svelte/src/internal/client/dom/template.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/svelte/src/internal/client/dom/template.js b/packages/svelte/src/internal/client/dom/template.js index 0d827218bc..64f8b6f817 100644 --- a/packages/svelte/src/internal/client/dom/template.js +++ b/packages/svelte/src/internal/client/dom/template.js @@ -4,6 +4,7 @@ import { hydrate_next, hydrate_node, hydrating, set_hydrate_node } from './hydra import { create_text, get_first_child, + get_next_sibling, is_firefox, create_element, create_fragment, @@ -310,6 +311,21 @@ export function text(value = '') { // if an {expression} is empty during SSR, we need to insert an empty text node node.before((node = create_text())); set_hydrate_node(node); + } else { + // Browsers may split text nodes > 65536 characters into multiple consecutive text nodes + // during HTML parsing. We need to merge them into a single text node. + var next = get_next_sibling(node); + var merged_text = /** @type {Text} */ (node).textContent; + + while (next !== null && next.nodeType === TEXT_NODE) { + merged_text += /** @type {Text} */ (next).textContent; + var to_remove = next; + next = get_next_sibling(next); + to_remove.remove(); + } + + // Update the text node with the merged content + /** @type {Text} */ (node).textContent = merged_text; } assign_nodes(node, node);