Skip to content

Commit 777c8ef

Browse files
cooolbrosbenmccannteemingcdummdidumm
authored
fix: tighten up preloadCode (#12217)
support absolute URLs with `data-sveltekit-preload-code="viewport"` and reroutes for preloadCode in general --------- Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> Co-authored-by: Chew Tee Ming <chew.tee.ming@nindatech.com> Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
1 parent 0142dd8 commit 777c8ef

File tree

16 files changed

+163
-19
lines changed

16 files changed

+163
-19
lines changed

.changeset/fluffy-coats-laugh.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@sveltejs/kit": patch
3+
---
4+
5+
fix: support absolute URLs and reroutes with `data-sveltekit-preload-code="viewport"`

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

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -426,9 +426,15 @@ async function _preload_data(intent) {
426426
return load_cache.promise;
427427
}
428428

429-
/** @param {URL} url */
429+
/**
430+
* @param {URL} url
431+
* @returns {Promise<void>}
432+
*/
430433
async function _preload_code(url) {
431-
const route = routes.find((route) => route.exec(get_url_path(url)));
434+
const rerouted = get_rerouted_url(url);
435+
if (!rerouted) return;
436+
437+
const route = routes.find((route) => route.exec(get_url_path(rerouted)));
432438

433439
if (route) {
434440
await Promise.all([...route.layouts, route.leaf].map((load) => load?.[1]()));
@@ -1189,16 +1195,11 @@ async function load_root_error_page({ status, error, url, route }) {
11891195
}
11901196

11911197
/**
1192-
* Resolve the full info (which route, params, etc.) for a client-side navigation from the URL,
1193-
* taking the reroute hook into account. If this isn't a client-side-navigation (or the URL is undefined),
1194-
* returns undefined.
1195-
* @param {URL | undefined} url
1196-
* @param {boolean} invalidating
1198+
* Resolve the relative rerouted URL for a client-side navigation
1199+
* @param {URL} url
1200+
* @returns {URL | undefined}
11971201
*/
1198-
function get_navigation_intent(url, invalidating) {
1199-
if (!url) return;
1200-
if (is_external_url(url, base, app.hash)) return;
1201-
1202+
function get_rerouted_url(url) {
12021203
// reroute could alter the given URL, so we pass a copy
12031204
let rerouted;
12041205
try {
@@ -1225,9 +1226,26 @@ function get_navigation_intent(url, invalidating) {
12251226
}
12261227

12271228
// fall back to native navigation
1228-
return undefined;
1229+
return;
12291230
}
12301231

1232+
return rerouted;
1233+
}
1234+
1235+
/**
1236+
* Resolve the full info (which route, params, etc.) for a client-side navigation from the URL,
1237+
* taking the reroute hook into account. If this isn't a client-side-navigation (or the URL is undefined),
1238+
* returns undefined.
1239+
* @param {URL | undefined} url
1240+
* @param {boolean} invalidating
1241+
*/
1242+
function get_navigation_intent(url, invalidating) {
1243+
if (!url) return;
1244+
if (is_external_url(url, base, app.hash)) return;
1245+
1246+
const rerouted = get_rerouted_url(url);
1247+
if (!rerouted) return;
1248+
12311249
const path = get_url_path(rerouted);
12321250

12331251
for (const route of routes) {
@@ -1942,13 +1960,20 @@ export function preloadCode(pathname) {
19421960
const url = new URL(pathname, current.url);
19431961

19441962
if (DEV) {
1963+
if (!pathname.startsWith('/')) {
1964+
throw new Error(
1965+
'argument passed to preloadCode must be a pathname (i.e. "/about" rather than "http://example.com/about"'
1966+
);
1967+
}
1968+
19451969
if (!pathname.startsWith(base)) {
19461970
throw new Error(
1947-
`pathnames passed to preloadCode must start with \`paths.base\` (i.e. "${base}${pathname}" rather than "${pathname}")`
1971+
`pathname passed to preloadCode must start with \`paths.base\` (i.e. "${base}${pathname}" rather than "${pathname}")`
19481972
);
19491973
}
19501974

1951-
if (!routes.find((route) => route.exec(get_url_path(url)))) {
1975+
const rerouted = get_rerouted_url(url);
1976+
if (!rerouted || !routes.find((route) => route.exec(get_url_path(rerouted)))) {
19521977
throw new Error(`'${pathname}' did not match any routes`);
19531978
}
19541979
}

packages/kit/test/ambient.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ declare global {
1616
const preloadData: (url: string) => Promise<void>;
1717
const beforeNavigate: (fn: (url: URL) => void | boolean) => void;
1818
const afterNavigate: (fn: () => void) => void;
19-
const preloadCode: (...urls: string[]) => Promise<void>;
19+
const preloadCode: (pathname: string) => Promise<void>;
2020
}
2121

2222
export {};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<div style="height: 200vh"></div>
2+
3+
<a
4+
id="viewport"
5+
href="/data-sveltekit/preload-code/target/viewport"
6+
data-sveltekit-preload-code="viewport">viewport</a
7+
>
8+
<a id="hover" href="/data-sveltekit/preload-code/target/hover" data-sveltekit-preload-code="hover"
9+
>hover</a
10+
>
11+
<a id="tap" href="/data-sveltekit/preload-code/target/tap" data-sveltekit-preload-code="tap">tap</a>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export function load() {
2+
return {
3+
name: 'eager'
4+
};
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
export let data;
3+
</script>
4+
5+
<h1>{data.name}</h1>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export function load() {
2+
return {
3+
name: 'hover'
4+
};
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
export let data;
3+
</script>
4+
5+
<h1>{data.name}</h1>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export function load() {
2+
return {
3+
name: 'tap'
4+
};
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
export let data;
3+
</script>
4+
5+
<h1>{data.name}</h1>

0 commit comments

Comments
 (0)