From 2262a1196d10d2fba1f843d76a175d636707ae5a Mon Sep 17 00:00:00 2001
From: Martin Trapp <94928215+martrapp@users.noreply.github.com>
Date: Sat, 8 Mar 2025 08:57:05 +0100
Subject: [PATCH] ClientRouter: prevent double execution of scripts when custom
swap() only swaps parts of the DOM
---
.changeset/lazy-kings-rush.md | 5 +++++
.../src/pages/partial-swap.astro | 20 +++++++++++++++++++
packages/astro/e2e/view-transitions.test.js | 15 ++++++++++++++
packages/astro/src/transitions/router.ts | 1 +
4 files changed, 41 insertions(+)
create mode 100644 .changeset/lazy-kings-rush.md
create mode 100644 packages/astro/e2e/fixtures/view-transitions/src/pages/partial-swap.astro
diff --git a/.changeset/lazy-kings-rush.md b/.changeset/lazy-kings-rush.md
new file mode 100644
index 0000000000..e3eecd832d
--- /dev/null
+++ b/.changeset/lazy-kings-rush.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fixes an edge case where the client router executed scripts twice when used with a custom swap function that only swaps parts of the DOM.
diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/partial-swap.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/partial-swap.astro
new file mode 100644
index 0000000000..40e0578519
--- /dev/null
+++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/partial-swap.astro
@@ -0,0 +1,20 @@
+---
+import { ClientRouter } from "astro:transitions";
+---
+
+
+
+
+
+
+
+
+ Astro
+
+ revisit
+ revisit
+
+
diff --git a/packages/astro/e2e/view-transitions.test.js b/packages/astro/e2e/view-transitions.test.js
index 76287e8782..73546ba4e8 100644
--- a/packages/astro/e2e/view-transitions.test.js
+++ b/packages/astro/e2e/view-transitions.test.js
@@ -1619,4 +1619,19 @@ test.describe('View Transitions', () => {
await expect(page).toHaveTitle('Page 1');
expect(lines.join('')).toBe('312233');
});
+
+ test('initial scripts are not re-executed after partial swap', async ({ page, astro }) => {
+ let consoleErrors = [];
+ page.on('console', (msg) => {
+ const txt = msg.text();
+ txt.startsWith("[test] ") && consoleErrors.push(txt.substring(7));
+ });
+ await page.goto(astro.resolveUrl('/partial-swap'));
+ await page.waitForURL('**/partial-swap');
+ await page.click('#link2');
+ await page.waitForURL('**/partial-swap?v=2');
+ await page.click('#link3');
+ await page.waitForURL('**/partial-swap?v=3');
+ expect(consoleErrors.join(", "), 'There should only be two executions').toEqual("head script, body script");
+ });
});
diff --git a/packages/astro/src/transitions/router.ts b/packages/astro/src/transitions/router.ts
index 0af04940a4..659f171360 100644
--- a/packages/astro/src/transitions/router.ts
+++ b/packages/astro/src/transitions/router.ts
@@ -649,6 +649,7 @@ if (inBrowser) {
}
for (const script of document.getElementsByTagName('script')) {
detectScriptExecuted(script);
+ script.dataset.astroExec = '';
}
}