diff --git a/.changeset/famous-knives-sneeze.md b/.changeset/famous-knives-sneeze.md
new file mode 100644
index 0000000000..9c7dcb42d3
--- /dev/null
+++ b/.changeset/famous-knives-sneeze.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: ensure implicit children snippet renders correctly
diff --git a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js
index 4f8e510709..37f4cc757f 100644
--- a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js
+++ b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js
@@ -1125,11 +1125,17 @@ const template_visitors = {
);
},
RenderTag(node, context) {
- const snippet_function = context.state.options.dev
+ const state = context.state;
+ const [anchor, anchor_id] = serialize_anchor(state);
+
+ state.init.push(anchor);
+ state.template.push(t_expression(anchor_id));
+
+ const snippet_function = state.options.dev
? b.call('$.validate_snippet', node.expression)
: node.expression;
if (node.argument) {
- context.state.template.push(
+ state.template.push(
t_statement(
b.stmt(
b.call(
@@ -1141,8 +1147,10 @@ const template_visitors = {
)
);
} else {
- context.state.template.push(t_statement(b.stmt(b.call(snippet_function, b.id('$$payload')))));
+ state.template.push(t_statement(b.stmt(b.call(snippet_function, b.id('$$payload')))));
}
+
+ state.template.push(t_expression(anchor_id));
},
ClassDirective(node) {
error(node, 'INTERNAL', 'Node should have been handled elsewhere');
@@ -1435,8 +1443,6 @@ const template_visitors = {
state.template.push(t_expression(id));
},
SnippetBlock(node, context) {
- const [dec, id] = serialize_anchor(context.state);
-
// TODO hoist where possible
/** @type {import('estree').Pattern[]} */
const args = [b.id('$$payload')];
@@ -1444,18 +1450,11 @@ const template_visitors = {
args.push(node.context);
}
- const out = b.member_id('$$payload.out');
-
context.state.init.push(
b.function_declaration(
node.expression,
args,
- b.block([
- dec,
- b.stmt(b.assignment('+=', out, id)),
- .../** @type {import('estree').BlockStatement} */ (context.visit(node.body)).body,
- b.stmt(b.assignment('+=', out, id))
- ])
+ /** @type {import('estree').BlockStatement} */ (context.visit(node.body))
)
);
if (context.state.options.dev) {
diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-dynamic-children/Button.svelte b/packages/svelte/tests/runtime-runes/samples/snippet-dynamic-children/Button.svelte
new file mode 100644
index 0000000000..bf8ea31e99
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/snippet-dynamic-children/Button.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-dynamic-children/_config.js b/packages/svelte/tests/runtime-runes/samples/snippet-dynamic-children/_config.js
new file mode 100644
index 0000000000..cd15ff7212
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/snippet-dynamic-children/_config.js
@@ -0,0 +1,16 @@
+import { flushSync } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ html: ``,
+
+ async test({ assert, target }) {
+ const [b1] = target.querySelectorAll('button');
+
+ flushSync(() => {
+ b1?.click();
+ });
+
+ assert.htmlEqual(target.innerHTML, ``);
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/snippet-dynamic-children/main.svelte b/packages/svelte/tests/runtime-runes/samples/snippet-dynamic-children/main.svelte
new file mode 100644
index 0000000000..55a095bf3c
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/snippet-dynamic-children/main.svelte
@@ -0,0 +1,13 @@
+
+
+