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/mighty-kiwis-laugh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

fix: correctly preload links on `mousedown`/`touchstart`
4 changes: 2 additions & 2 deletions packages/kit/src/runtime/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -1677,8 +1677,6 @@ function setup_preload() {
const a = find_anchor(element, container);
if (!a || a === current_a) return;

current_a = a;

const { url, external, download } = get_link_info(a, base, app.hash);
if (external || download) return;

Expand All @@ -1689,6 +1687,7 @@ function setup_preload() {

if (!options.reload && !same_url) {
if (priority <= options.preload_data) {
current_a = a;
const intent = await get_navigation_intent(url, false);
if (intent) {
if (DEV) {
Expand All @@ -1707,6 +1706,7 @@ function setup_preload() {
}
}
} else if (priority <= options.preload_code) {
current_a = a;
void _preload_code(/** @type {URL} */ (url));
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
<a id="eager" href="/data-sveltekit/preload-code/target/eager" data-sveltekit-preload-code="eager"
>eager</a
>

<div style="height: 200vh"></div>

<a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
>three</a
>
</div>

<a id="tap" href="/data-sveltekit/preload-data/target" data-sveltekit-preload-data="tap">tap</a>
68 changes: 51 additions & 17 deletions packages/kit/test/apps/basics/test/client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -827,32 +827,56 @@ test.describe('Invalidation', () => {
test.describe('data-sveltekit attributes', () => {
test('data-sveltekit-preload-code', async ({ page }) => {
/** @type {string[]} */
const requests = [];
page.on('request', (r) => {
requests.push(r.url());
const responses = [];

const nodes_location = process.env.DEV
? '.svelte-kit/generated/client/nodes/'
: '/_app/immutable/nodes/';

page.on('response', async (response) => {
const url = response.url();
if (url.includes(nodes_location)) {
responses.push(url);
}
});

// eager
await page.goto('/data-sveltekit/preload-code');
expect(requests.length).toBeGreaterThanOrEqual(1);
await page.locator('#eager').hover();
await page.locator('#eager').dispatchEvent('touchstart');
// expect 4 nodes on initial load: root layout, root error, current page, and eager preload
expect(responses.length).toEqual(4);

// viewport
requests.length = 0;
responses.length = 0;
page.locator('#viewport').scrollIntoViewIfNeeded();
await Promise.all([page.waitForTimeout(100), page.waitForLoadState('networkidle')]);
expect(requests.length).toBeGreaterThanOrEqual(1);
await page.locator('#viewport').hover();
await page.locator('#viewport').dispatchEvent('touchstart');
await Promise.all([
page.waitForTimeout(100), // wait for preloading to start
page.waitForLoadState('networkidle') // wait for preloading to finish
]);
expect(responses.length).toEqual(1);

// hover
requests.length = 0;
await page.locator('#hover').dispatchEvent('mousemove');
await Promise.all([page.waitForTimeout(100), page.waitForLoadState('networkidle')]);
expect(requests.length).toBeGreaterThanOrEqual(1);
responses.length = 0;
await page.locator('#hover').hover();
await page.locator('#hover').dispatchEvent('touchstart');
await Promise.all([
page.waitForTimeout(100), // wait for preloading to start
page.waitForLoadState('networkidle') // wait for preloading to finish
]);
expect(responses.length).toEqual(1);

// tap
requests.length = 0;
responses.length = 0;
await page.locator('#tap').hover();
await page.locator('#tap').dispatchEvent('touchstart');
await Promise.all([page.waitForTimeout(100), page.waitForLoadState('networkidle')]);
expect(requests.length).toBeGreaterThanOrEqual(1);
await Promise.all([
page.waitForTimeout(100), // wait for preloading to start
page.waitForLoadState('networkidle') // wait for preloading to finish
]);
expect(responses.length).toEqual(1);
});

test('data-sveltekit-preload-data', async ({ page }) => {
Expand All @@ -875,7 +899,7 @@ test.describe('data-sveltekit attributes', () => {
});

await page.goto('/data-sveltekit/preload-data');
await page.locator('#one').dispatchEvent('mousemove');
await page.locator('#one').hover();
await Promise.all([
page.waitForTimeout(100), // wait for preloading to start
page.waitForLoadState('networkidle') // wait for preloading to finish
Expand All @@ -884,7 +908,7 @@ test.describe('data-sveltekit attributes', () => {

requests.length = 0;
await page.goto('/data-sveltekit/preload-data');
await page.locator('#two').dispatchEvent('mousemove');
await page.locator('#two').hover();
await Promise.all([
page.waitForTimeout(100), // wait for preloading to start
page.waitForLoadState('networkidle') // wait for preloading to finish
Expand All @@ -893,12 +917,22 @@ test.describe('data-sveltekit attributes', () => {

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

requests.length = 0;
await page.goto('/data-sveltekit/preload-data');
await page.locator('#tap').hover();
await page.locator('#tap').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(1);
});

test('data-sveltekit-preload-data network failure does not trigger navigation', async ({
Expand Down
Loading