diff --git a/.changeset/nested-boundary-hydrate.md b/.changeset/nested-boundary-hydrate.md new file mode 100644 index 0000000000..dbbf545a5d --- /dev/null +++ b/.changeset/nested-boundary-hydrate.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: recover when an unexpected node replaces a nested boundary comment during hydration diff --git a/packages/svelte/src/internal/client/dom/blocks/boundary.js b/packages/svelte/src/internal/client/dom/blocks/boundary.js index 7ca0c47a81..88e8caae56 100644 --- a/packages/svelte/src/internal/client/dom/blocks/boundary.js +++ b/packages/svelte/src/internal/client/dom/blocks/boundary.js @@ -32,6 +32,7 @@ import { hydrate_node, hydrating, next, + read_hydration_instruction, skip_nodes, set_hydrate_node } from '../hydration.js'; @@ -164,16 +165,18 @@ export class Boundary { this.#effect = block(() => { if (hydrating) { - const comment = /** @type {Comment} */ (this.#hydrate_open); + const comment_data = read_hydration_instruction( + /** @type {TemplateNode} */ (this.#hydrate_open) + ); hydrate_next(); - const server_rendered_pending = comment.data === HYDRATION_START_ELSE; - const server_rendered_failed = comment.data.startsWith(HYDRATION_START_FAILED); + const server_rendered_pending = comment_data === HYDRATION_START_ELSE; + const server_rendered_failed = comment_data.startsWith(HYDRATION_START_FAILED); if (server_rendered_failed) { // Server rendered the failed snippet - hydrate it. // The serialized error is embedded in the comment: - const serialized_error = JSON.parse(comment.data.slice(HYDRATION_START_FAILED.length)); + const serialized_error = JSON.parse(comment_data.slice(HYDRATION_START_FAILED.length)); this.#hydrate_failed_content(serialized_error); } else if (server_rendered_pending) { this.#hydrate_pending_content(); diff --git a/packages/svelte/tests/hydration/samples/boundary-nested-extra-node/_config.js b/packages/svelte/tests/hydration/samples/boundary-nested-extra-node/_config.js new file mode 100644 index 0000000000..d5b5a00c0d --- /dev/null +++ b/packages/svelte/tests/hydration/samples/boundary-nested-extra-node/_config.js @@ -0,0 +1,6 @@ +import { test } from '../../test'; + +// https://github.com/sveltejs/svelte/issues/18924 +export default test({ + expect_hydration_error: true +}); diff --git a/packages/svelte/tests/hydration/samples/boundary-nested-extra-node/_expected.html b/packages/svelte/tests/hydration/samples/boundary-nested-extra-node/_expected.html new file mode 100644 index 0000000000..0d29b99446 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/boundary-nested-extra-node/_expected.html @@ -0,0 +1 @@ +
inner
inner
inner
+ {#snippet failed()} +inner failed
+ {/snippet} +outer failed
+ {/snippet} +