Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/small-coins-show.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

fix: preload links if href changes
11 changes: 6 additions & 5 deletions packages/kit/src/runtime/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -1860,8 +1860,8 @@ if (import.meta.hot) {
function setup_preload() {
/** @type {NodeJS.Timeout} */
let mousemove_timeout;
/** @type {Element} */
let current_a;
/** @type {{ element: Element | SVGAElement | undefined; href: string | SVGAnimatedString | undefined }} */
let current_a = { element: undefined, href: undefined };
/** @type {PreloadDataPriority} */
let current_priority;

Expand Down Expand Up @@ -1903,7 +1903,8 @@ function setup_preload() {
const a = find_anchor(element, container);

// we don't want to preload data again if the user has already hovered/tapped
const interacted = a === current_a && priority >= current_priority;
const interacted =
a === current_a.element && a?.href === current_a.href && priority >= current_priority;
if (!a || interacted) return;

const { url, external, download } = get_link_info(a, base, app.hash);
Expand All @@ -1916,7 +1917,7 @@ function setup_preload() {
if (options.reload || same_url) return;

if (priority <= options.preload_data) {
current_a = a;
current_a = { element: a, href: a.href };
// we don't want to preload data again on tap if we've already preloaded it on hover
current_priority = PRELOAD_PRIORITIES.tap;

Expand All @@ -1938,7 +1939,7 @@ function setup_preload() {
void _preload_data(intent);
}
} else if (priority <= options.preload_code) {
current_a = a;
current_a = { element: a, href: a.href };
current_priority = priority;
void _preload_code(/** @type {URL} */ (url));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
<script>
let x = 0;
</script>

<a id="one" href="/data-sveltekit/preload-data/target" data-sveltekit-preload-data>one</a>

<div data-sveltekit-preload-data>
Expand All @@ -15,3 +19,8 @@
data-sveltekit-preload-code="hover"
data-sveltekit-preload-data="tap">hover for code then tap for data</a
>

<a id="dynamic" data-sveltekit-preload-data="hover" href="/data-sveltekit/preload-data/target?x={x}"
>dynamic</a
>
<button id="change_dynamic" type="button" on:click={() => x++}>change dynamic</button>
27 changes: 27 additions & 0 deletions packages/kit/test/apps/basics/test/client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,33 @@
page.waitForLoadState('networkidle') // wait for preloading to finish
]);
expect(requests.length).toBe(2);

requests.length = 0;
await page.goto('/data-sveltekit/preload-data');
await page.locator('#dynamic').hover();
await page.locator('#dynamic').dispatchEvent('touchstart');
await Promise.all([
page.waitForTimeout(100), // wait for preloading to start
page.waitForLoadState('networkidle') // wait for preloading to finish
]);
expect(requests.length).toBe(2);
await page.waitForTimeout(100);
await page.locator('#dynamic').hover();
await page.locator('#dynamic').dispatchEvent('touchstart');
await Promise.all([
page.waitForTimeout(100), // wait for preloading to start
page.waitForLoadState('networkidle') // wait for preloading to finish
]);
expect(requests.length).toBe(2);
await page.locator('#change_dynamic').click();
await page.waitForTimeout(100);
await page.locator('#dynamic').hover();
await page.locator('#dynamic').dispatchEvent('touchstart');
await Promise.all([
page.waitForTimeout(100), // wait for preloading to start
page.waitForLoadState('networkidle') // wait for preloading to finish
]);
expect(requests.length).toBe(3);
});

test('data-sveltekit-preload-data network failure does not trigger navigation', async ({
Expand Down Expand Up @@ -1333,7 +1360,7 @@
await expect(page.locator('p.streamed')).toHaveText('streamed');
});

test('Catches fetch errors from server load functions (direct hit)', async ({ page }) => {

Check warning on line 1363 in packages/kit/test/apps/basics/test/client.test.js

View workflow job for this annotation

GitHub Actions / test-kit (22, ubuntu-latest, chromium)

flaky test: Catches fetch errors from server load functions (direct hit)

retries: 2
page.goto('/streaming/server-error');
await expect(page.locator('p.eager')).toHaveText('eager');
await expect(page.locator('p.fail')).toHaveText('fail');
Expand Down
Loading