Repository: sveltejs/kit
Pull request #7580 (2022-11-10 03:08:36)

[fix] prefetch should ignore links ignored by the router
### Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
- [ ] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
- [ ] This message body should clearly illustrate what problems it solves.
- [ ] Ideally, include a test that fails without this PR but passes with it.

### Tests
- [x] Run the tests with `pnpm test` and lint the project with `pnpm lint` and `pnpm check`

### Changesets
- [x] If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running `pnpm changeset` and following the prompts. All changesets should be `patch` until SvelteKit 1.0


changeset-bot[bot]: ###  🦋  Changeset detected

Latest commit: e7d296ae189527dfabb6530edba22c8b5737eb41

**The changes in this PR will be included in the next version bump.**

<details><summary>This PR includes changesets to release 1 package</summary>

  | Name          | Type  |
| ------------- | ----- |
| @sveltejs/kit | Patch |

</details>

Not sure what this means? [Click here  to learn what changesets are](https://github.com/changesets/changesets/blob/master/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add another changeset to this PR](https://github.com/gtm-nayan/sveltekit/new/prefetch-filter?filename=.changeset/pink-eels-join.md&value=---%0A%22%40sveltejs%2Fkit%22%3A%20patch%0A---%0A%0A%5Bfix%5D%20prefetch%20should%20ignore%20links%20ignored%20by%20the%20router%0A)



Patch:
diff --git a/.changeset/gentle-shoes-run.md b/.changeset/gentle-shoes-run.md
new file mode 100644
index 000000000..bb65d8db3
--- /dev/null
+++ b/.changeset/gentle-shoes-run.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+[fix] prefetch should ignore links ignored by the router
diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js
index b22cb6dd0..db7a07b0f 100644
--- a/packages/kit/src/runtime/client/client.js
+++ b/packages/kit/src/runtime/client/client.js
@@ -1359,9 +1359,9 @@ export function create_client({ target, base, trailing_slash }) {
 
 			/** @param {Event} event */
 			const trigger_prefetch = (event) => {
-				const { url, options } = find_anchor(event);
-				if (url && options.prefetch) {
-					if (is_external_url(url)) return;
+				const { url, options, has } = find_anchor(event);
+				if (url && options.prefetch && !is_external_url(url)) {
+					if (options.reload || has.rel_external || has.target || has.download) return;
 					prefetch(url);
 				}
 			};
@@ -1393,7 +1393,7 @@ export function create_client({ target, base, trailing_slash }) {
 				if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
 				if (event.defaultPrevented) return;
 
-				const { a, url, options } = find_anchor(event);
+				const { a, url, options, has } = find_anchor(event);
 				if (!a || !url) return;
 
 				const is_svg_a_element = a instanceof SVGAElement;
@@ -1413,15 +1413,10 @@ export function create_client({ target, base, trailing_slash }) {
 				)
 					return;
 
-				if (a.hasAttribute('download')) return;
+				if (has.download) return;
 
 				// Ignore the following but fire beforeNavigate
-				const rel = (a.getAttribute('rel') || '').split(/\s+/);
-				if (
-					rel.includes('external') ||
-					options.reload ||
-					(is_svg_a_element ? a.target.baseVal : a.target)
-				) {
+				if (options.reload || has.rel_external || has.target) {
 					const navigation = before_navigate({ url, type: 'link' });
 					if (!navigation) {
 						event.preventDefault();
diff --git a/packages/kit/src/runtime/client/utils.js b/packages/kit/src/runtime/client/utils.js
index 25d183dd3..fca6edf23 100644
--- a/packages/kit/src/runtime/client/utils.js
+++ b/packages/kit/src/runtime/client/utils.js
@@ -58,7 +58,14 @@ export function find_anchor(event) {
 			noscroll,
 			prefetch,
 			reload
-		}
+		},
+		has: a
+			? {
+					rel_external: (a.getAttribute('rel') || '').split(/\s+/).includes('external'),
+					download: a.hasAttribute('download'),
+					target: !!(a instanceof SVGAElement ? a.target.baseVal : a.target)
+			  }
+			: {}
 	};
 }
 


Test patch:
diff --git a/packages/kit/test/apps/basics/src/routes/load/invalidation/depends/+page.svelte b/packages/kit/test/apps/basics/src/routes/load/invalidation/depends/+page.svelte
index 1ce33105c..e402d30d5 100644
--- a/packages/kit/test/apps/basics/src/routes/load/invalidation/depends/+page.svelte
+++ b/packages/kit/test/apps/basics/src/routes/load/invalidation/depends/+page.svelte
@@ -9,7 +9,7 @@
 <button
 	type="button"
 	class="shared"
-	on:click={() => invalidate('invalidate-depends:shared')}
+	on:click={() => (window.promise = invalidate('invalidate-depends:shared'))}
 >
 	invalidate shared
 </button>
@@ -18,7 +18,7 @@
 <button
 	type="button"
 	class="server"
-	on:click={() => invalidate('invalidate-depends:server')}
+	on:click={() => (window.promise = invalidate('invalidate-depends:server'))}
 >
 	invalidate server
 </button>
diff --git a/packages/kit/test/apps/basics/test/client.test.js b/packages/kit/test/apps/basics/test/client.test.js
index 172077007..8a04dd861 100644
--- a/packages/kit/test/apps/basics/test/client.test.js
+++ b/packages/kit/test/apps/basics/test/client.test.js
@@ -861,8 +861,8 @@ test.describe.serial('Invalidation', () => {
 		expect(server).toBeDefined();
 		expect(shared).toBeDefined();
 
-		await Promise.all([page.click('button.server'), page.waitForLoadState('networkidle')]);
-		await page.waitForTimeout(200);
+		await page.click('button.server');
+		await page.evaluate(() => window.promise);
 		const next_server = await page.textContent('p.server');
 		const next_shared = await page.textContent('p.shared');
 		expect(server).not.toBe(next_server);
@@ -876,8 +876,8 @@ test.describe.serial('Invalidation', () => {
 		expect(server).toBeDefined();
 		expect(shared).toBeDefined();
 
-		await Promise.all([page.click('button.shared'), page.waitForLoadState('networkidle')]);
-		await page.waitForTimeout(200);
+		await page.click('button.shared');
+		await page.evaluate(() => window.promise);
 		const next_server = await page.textContent('p.server');
 		const next_shared = await page.textContent('p.shared');
 		expect(server).toBe(next_server);