From cf35a22568be2e767c419a6b8ac36fe73c270eb3 Mon Sep 17 00:00:00 2001 From: ComputerGuy <63362464+Ocean-OS@users.noreply.github.com> Date: Tue, 23 Sep 2025 03:04:45 -0700 Subject: [PATCH] fix: allow `{@html await ...}` and async snippets on the server (#16817) Fixes #16816 Fixes #16811 --------- Co-authored-by: Simon Holthausen Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com> --- .changeset/long-spies-hope.md | 5 +++++ .../compiler/phases/3-transform/server/visitors/HtmlTag.js | 7 ++++++- .../phases/3-transform/server/visitors/SnippetBlock.js | 5 +++++ .../samples/async-html-tag/_expected.html | 1 + .../samples/async-html-tag/main.svelte | 1 + .../samples/async-snippet/_expected.html | 1 + .../samples/async-snippet/main.svelte | 6 ++++++ 7 files changed, 25 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 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/.changeset/long-spies-hope.md b/.changeset/long-spies-hope.md new file mode 100644 index 0000000000..6bb8184c64 --- /dev/null +++ b/.changeset/long-spies-hope.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: allow `{@html await ...}` and snippets with async content 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 9e857a9308..9a3d2830ac 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/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js index 7ae2a8e037..5fc865ec58 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-html-tag/_expected.html b/packages/svelte/tests/server-side-rendering/samples/async-html-tag/_expected.html new file mode 100644 index 0000000000..5be0be37f2 --- /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 0000000000..2d556e4d5b --- /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 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 0000000000..5be0be37f2 --- /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 0000000000..a6f2ac7b09 --- /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()}