Skip to content

Commit 4315e0b

Browse files
authored
fix: prevent beforeNavigate() for download links (#9660)
* do not call before navigate for downloads * changeset * add test * remove # from test download link
1 parent 439a185 commit 4315e0b

File tree

5 files changed

+29
-8
lines changed

5 files changed

+29
-8
lines changed

.changeset/shiny-eels-greet.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': minor
3+
---
4+
5+
fix: do not call beforeNavigate for download links

packages/kit/src/runtime/client/client.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,8 +1266,8 @@ export function create_client(app, target) {
12661266
const a = find_anchor(element, container);
12671267
if (!a) return;
12681268

1269-
const { url, external } = get_link_info(a, base);
1270-
if (external) return;
1269+
const { url, external, download } = get_link_info(a, base);
1270+
if (external || download) return;
12711271

12721272
const options = get_router_options(a);
12731273

@@ -1300,8 +1300,8 @@ export function create_client(app, target) {
13001300
observer.disconnect();
13011301

13021302
for (const a of container.querySelectorAll('a')) {
1303-
const { url, external } = get_link_info(a, base);
1304-
if (external) continue;
1303+
const { url, external, download } = get_link_info(a, base);
1304+
if (external || download) continue;
13051305

13061306
const options = get_router_options(a);
13071307
if (options.reload) continue;
@@ -1517,7 +1517,7 @@ export function create_client(app, target) {
15171517
const a = find_anchor(/** @type {Element} */ (event.composedPath()[0]), container);
15181518
if (!a) return;
15191519

1520-
const { url, external, target } = get_link_info(a, base);
1520+
const { url, external, target, download } = get_link_info(a, base);
15211521
if (!url) return;
15221522

15231523
// bail out before `beforeNavigate` if link opens in a different tab
@@ -1545,6 +1545,8 @@ export function create_client(app, target) {
15451545
)
15461546
return;
15471547

1548+
if (download) return;
1549+
15481550
// Ignore the following but fire beforeNavigate
15491551
if (external || options.reload) {
15501552
if (before_navigate({ url, type: 'link' })) {

packages/kit/src/runtime/client/utils.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,11 @@ export function get_link_info(a, base) {
133133
!url ||
134134
!!target ||
135135
is_external_url(url, base) ||
136-
(a.getAttribute('rel') || '').split(/\s+/).includes('external') ||
137-
a.hasAttribute('download');
136+
(a.getAttribute('rel') || '').split(/\s+/).includes('external');
138137

139-
return { url, external, target };
138+
const download = url?.origin === location.origin && a.hasAttribute('download');
139+
140+
return { url, external, target, download };
140141
}
141142

142143
/**

packages/kit/test/apps/basics/src/routes/before-navigate/prevent-navigation/+page.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@
2020
<a href="/before-navigate/prevent-navigation?x=1">self</a>
2121
<a href="https://google.com" target="_blank" rel="noreferrer">_blank</a>
2222
<a href="https://google.de">external</a>
23+
<a download href="">external</a>
2324
<pre>{times_triggered} {unload} {navigation_type}</pre>

packages/kit/test/apps/basics/test/cross-platform/client.test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,18 @@ test.describe('beforeNavigate', () => {
213213

214214
expect(await page.innerHTML('pre')).toBe('2 false goto');
215215
});
216+
217+
test('is triggered after clicking a download link', async ({ page, baseURL }) => {
218+
await page.goto('/before-navigate/prevent-navigation');
219+
220+
await page.click('a[download]');
221+
expect(await page.innerHTML('pre')).toBe('0 false undefined');
222+
223+
await page.click('a[href="/before-navigate/a"]');
224+
225+
expect(page.url()).toBe(baseURL + '/before-navigate/prevent-navigation');
226+
expect(await page.innerHTML('pre')).toBe('1 false link');
227+
});
216228
});
217229

218230
test.describe('Scrolling', () => {

0 commit comments

Comments
 (0)