diff --git a/.changeset/two-places-speak.md b/.changeset/two-places-speak.md new file mode 100644 index 0000000000..957377b26b --- /dev/null +++ b/.changeset/two-places-speak.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: prevent async render tag hydration mismatches diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/RenderTag.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/RenderTag.js index fe20e85e1b..ac671c0188 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/RenderTag.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/RenderTag.js @@ -37,7 +37,9 @@ export function RenderTag(node, context) { context.state.template.push(...optimiser.render_block([statement])); - if (!context.state.is_standalone) { + // If the render tag is wrapped in $.async, that $.async call already contains surrounding markers, + // so we don't need to (or rather must not, to avoid hydration mismatches) add our own. + if (!optimiser.is_async() && !context.state.is_standalone) { context.state.template.push(empty_comment); } } diff --git a/packages/svelte/tests/runtime-runes/samples/async-render-hydration/_config.js b/packages/svelte/tests/runtime-runes/samples/async-render-hydration/_config.js new file mode 100644 index 0000000000..2e37b0b9ac --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-render-hydration/_config.js @@ -0,0 +1,11 @@ +import { tick } from 'svelte'; +import { test } from '../../test'; + +export default test({ + mode: ['hydrate'], + + async test({ assert, target }) { + await tick(); + assert.htmlEqual(target.innerHTML, `Count: 1 Double: 2`); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/async-render-hydration/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-render-hydration/main.svelte new file mode 100644 index 0000000000..e26ff87567 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-render-hydration/main.svelte @@ -0,0 +1,15 @@ + + +Count: {count} + +{#snippet ssr(num: number)} + {num} +{/snippet} + +Double: {@render ssr(double)}