From 79a0c0d4d8faf305a1c1c536712139f569c9e431 Mon Sep 17 00:00:00 2001
From: jarrednorris <58517737+jarrednorrisdev@users.noreply.github.com>
Date: Tue, 6 Oct 2026 10:30:52 +0100
Subject: [PATCH] fix: attach event handlers that are assigned after a
top-level `await` in production (#18933)
Fixes #18932
---
.changeset/late-handlers-wait.md | 5 +++++
.../client/visitors/shared/events.js | 5 +++--
.../async-event-handler-blockers/_config.js | 19 +++++++++++++++++++
.../async-event-handler-blockers/main.svelte | 19 +++++++++++++++++++
4 files changed, 46 insertions(+), 2 deletions(-)
create mode 100644 .changeset/late-handlers-wait.md
create mode 100644 packages/svelte/tests/runtime-runes/samples/async-event-handler-blockers/_config.js
create mode 100644 packages/svelte/tests/runtime-runes/samples/async-event-handler-blockers/main.svelte
diff --git a/.changeset/late-handlers-wait.md b/.changeset/late-handlers-wait.md
new file mode 100644
index 0000000000..306a950c43
--- /dev/null
+++ b/.changeset/late-handlers-wait.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: attach event handlers that are assigned after a top-level `await` in production
diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/events.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/events.js
index f01bf08694..83c73a0279 100644
--- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/events.js
+++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/events.js
@@ -119,8 +119,9 @@ export function build_event_handler(node, metadata, context) {
// local variable can be assigned directly
// except in dev mode where when need $.apply()
- // in order to handle warnings.
- if (!dev && binding?.declaration_kind !== 'import') {
+ // in order to handle warnings, or when it is
+ // assigned after a top-level `await`
+ if (!dev && binding?.declaration_kind !== 'import' && !binding?.blocker) {
return handler;
}
}
diff --git a/packages/svelte/tests/runtime-runes/samples/async-event-handler-blockers/_config.js b/packages/svelte/tests/runtime-runes/samples/async-event-handler-blockers/_config.js
new file mode 100644
index 0000000000..f4dcbef823
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-event-handler-blockers/_config.js
@@ -0,0 +1,19 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ mode: ['client', 'hydrate'],
+ async test({ assert, target, window, logs }) {
+ await new Promise((r) => setTimeout(r));
+ await tick();
+
+ const button = target.querySelector('button');
+ const div = target.querySelector('div');
+
+ button?.click();
+ div?.dispatchEvent(new window.MouseEvent('mouseenter'));
+ window.dispatchEvent(new window.Event('resize'));
+
+ assert.deepEqual(logs, ['click', 'mouseenter', 'resize']);
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-event-handler-blockers/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-event-handler-blockers/main.svelte
new file mode 100644
index 0000000000..16bbac14a8
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-event-handler-blockers/main.svelte
@@ -0,0 +1,19 @@
+
+
+