diff --git a/packages/svelte/src/internal/client/dom/blocks/svelte-head.js b/packages/svelte/src/internal/client/dom/blocks/svelte-head.js index 02c4f62210..b6f6bc09a4 100644 --- a/packages/svelte/src/internal/client/dom/blocks/svelte-head.js +++ b/packages/svelte/src/internal/client/dom/blocks/svelte-head.js @@ -7,7 +7,7 @@ import { HYDRATION_END, HYDRATION_ERROR, HYDRATION_START } from '../../../../con import { hydration_mismatch } from '../../warnings.js'; /** - * @type {Node | undefined} + * @type {Node | null | undefined} */ let head_anchor; @@ -33,7 +33,7 @@ export function head(render_fn) { // There might be multiple head blocks in our app, so we need to account for each one needing independent hydration. if (head_anchor === undefined) { - head_anchor = /** @type {TemplateNode} */ (get_first_child(document.head)); + head_anchor = get_first_child(document.head); } while ( @@ -41,7 +41,7 @@ export function head(render_fn) { (head_anchor.nodeType !== COMMENT_NODE || /** @type {Comment} */ (head_anchor).data !== HYDRATION_START) ) { - head_anchor = /** @type {TemplateNode} */ (get_next_sibling(head_anchor)); + head_anchor = get_next_sibling(head_anchor); } // If we can't find an opening hydration marker, skip hydration (this can happen @@ -61,26 +61,28 @@ export function head(render_fn) { block(() => render_fn(anchor), HEAD_EFFECT); check_end(); } catch (error) { - // re-mount only this svelte:head + // Remount only this svelte:head if (was_hydrating && head_anchor && error === HYDRATION_ERROR) { // Here head_anchor is the node next after HYDRATION_START /** @type {Node | null} */ - let prev = head_anchor.previousSibling; - /** @type {Node | null} */ - let next = head_anchor; - // remove nodes that failed to hydrate - while ( - prev !== null && - (prev.nodeType !== COMMENT_NODE || /** @type {Comment} */ (prev).data !== HYDRATION_END) - ) { - document.head.removeChild(prev); - prev = next; - next = get_next_sibling(/** @type {Node} */ (next)); + let node = head_anchor.previousSibling; + // Remove nodes that failed to hydrate + while (node !== null) { + const removed = node; + node = get_next_sibling(node); + document.head.removeChild(removed); + if ( + removed.nodeType === COMMENT_NODE && + /** @type {Comment} */ (removed).data === HYDRATION_END + ) { + break; + } } - if (prev?.parentNode) document.head.removeChild(prev); - if (next !== null) { - // allow the next head block try to hydrate - head_anchor = set_hydrate_node(/** @type {TemplateNode} */ (next)); + // Setup hydration for the next svelte:head + if (node === null) { + head_anchor = null; + } else { + head_anchor = set_hydrate_node(/** @type {TemplateNode} */ (node)); } set_hydrating(false);