From 539af1711206e5724c1f4cd0e5ee2e665ca7e13a Mon Sep 17 00:00:00 2001
From: ComputerGuy <63362464+Ocean-OS@users.noreply.github.com>
Date: Mon, 22 Sep 2025 23:04:53 -0700
Subject: [PATCH 1/3] fix: allow `{@html await ...}` on the server
---
.changeset/long-spies-hope.md | 5 +++++
.../compiler/phases/3-transform/server/visitors/HtmlTag.js | 7 ++++++-
.../samples/async-html-tag/_expected.html | 1 +
.../samples/async-html-tag/main.svelte | 1 +
4 files changed, 13 insertions(+), 1 deletion(-)
create mode 100644 .changeset/long-spies-hope.md
create mode 100644 packages/svelte/tests/server-side-rendering/samples/async-html-tag/_expected.html
create mode 100644 packages/svelte/tests/server-side-rendering/samples/async-html-tag/main.svelte
diff --git a/.changeset/long-spies-hope.md b/.changeset/long-spies-hope.md
new file mode 100644
index 000000000000..15cd0dcef05b
--- /dev/null
+++ b/.changeset/long-spies-hope.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: allow `{@html await ...}` on the server
diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/HtmlTag.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/HtmlTag.js
index 9e857a930863..9a3d2830ac36 100644
--- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/HtmlTag.js
+++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/HtmlTag.js
@@ -9,5 +9,10 @@ import * as b from '#compiler/builders';
*/
export function HtmlTag(node, context) {
const expression = /** @type {Expression} */ (context.visit(node.expression));
- context.state.template.push(b.call('$.html', expression));
+ const call = b.call('$.html', expression);
+ context.state.template.push(
+ node.metadata.expression.has_await
+ ? b.stmt(b.call('$$renderer.push', b.thunk(call, true)))
+ : call
+ );
}
diff --git a/packages/svelte/tests/server-side-rendering/samples/async-html-tag/_expected.html b/packages/svelte/tests/server-side-rendering/samples/async-html-tag/_expected.html
new file mode 100644
index 000000000000..5be0be37f235
--- /dev/null
+++ b/packages/svelte/tests/server-side-rendering/samples/async-html-tag/_expected.html
@@ -0,0 +1 @@
+
this should work
\ No newline at end of file
diff --git a/packages/svelte/tests/server-side-rendering/samples/async-html-tag/main.svelte b/packages/svelte/tests/server-side-rendering/samples/async-html-tag/main.svelte
new file mode 100644
index 000000000000..2d556e4d5b9e
--- /dev/null
+++ b/packages/svelte/tests/server-side-rendering/samples/async-html-tag/main.svelte
@@ -0,0 +1 @@
+{@html await 'this should work'}
\ No newline at end of file
From c3d4221ad729505ac5cda82a0f9233c27608cc4a Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Tue, 23 Sep 2025 11:58:47 +0200
Subject: [PATCH 2/3] also fix snippet block, fixes #16811
---
.../phases/3-transform/server/visitors/SnippetBlock.js | 5 +++++
.../samples/async-snippet/_expected.html | 1 +
.../server-side-rendering/samples/async-snippet/main.svelte | 6 ++++++
3 files changed, 12 insertions(+)
create mode 100644 packages/svelte/tests/server-side-rendering/samples/async-snippet/_expected.html
create mode 100644 packages/svelte/tests/server-side-rendering/samples/async-snippet/main.svelte
diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js
index 7ae2a8e03793..5fc865ec586a 100644
--- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js
+++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js
@@ -3,6 +3,7 @@
/** @import { ComponentContext } from '../types.js' */
import { dev } from '../../../../state.js';
import * as b from '#compiler/builders';
+import { create_async_block } from './shared/utils.js';
/**
* @param {AST.SnippetBlock} node
@@ -15,6 +16,10 @@ export function SnippetBlock(node, context) {
/** @type {BlockStatement} */ (context.visit(node.body))
);
+ if (node.body.metadata.has_await) {
+ fn.body = b.block([create_async_block(fn.body)]);
+ }
+
// @ts-expect-error - TODO remove this hack once $$render_inner for legacy bindings is gone
fn.___snippet = true;
diff --git a/packages/svelte/tests/server-side-rendering/samples/async-snippet/_expected.html b/packages/svelte/tests/server-side-rendering/samples/async-snippet/_expected.html
new file mode 100644
index 000000000000..5be0be37f235
--- /dev/null
+++ b/packages/svelte/tests/server-side-rendering/samples/async-snippet/_expected.html
@@ -0,0 +1 @@
+this should work
\ No newline at end of file
diff --git a/packages/svelte/tests/server-side-rendering/samples/async-snippet/main.svelte b/packages/svelte/tests/server-side-rendering/samples/async-snippet/main.svelte
new file mode 100644
index 000000000000..a6f2ac7b09c5
--- /dev/null
+++ b/packages/svelte/tests/server-side-rendering/samples/async-snippet/main.svelte
@@ -0,0 +1,6 @@
+{#snippet foo()}
+ {@const x = await 'this should work'}
+ {x}
+{/snippet}
+
+{@render foo()}
From 4bd8d831d132b5ff492bfbd57276df8da789ae72 Mon Sep 17 00:00:00 2001
From: Simon H <5968653+dummdidumm@users.noreply.github.com>
Date: Tue, 23 Sep 2025 11:59:35 +0200
Subject: [PATCH 3/3] fix changelog
---
.changeset/long-spies-hope.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.changeset/long-spies-hope.md b/.changeset/long-spies-hope.md
index 15cd0dcef05b..6bb8184c6439 100644
--- a/.changeset/long-spies-hope.md
+++ b/.changeset/long-spies-hope.md
@@ -2,4 +2,4 @@
'svelte': patch
---
-fix: allow `{@html await ...}` on the server
+fix: allow `{@html await ...}` and snippets with async content on the server