diff --git a/.changeset/brown-jars-lick.md b/.changeset/brown-jars-lick.md new file mode 100644 index 000000000000..0d824e445f47 --- /dev/null +++ b/.changeset/brown-jars-lick.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes an issue where links with the same pathname as the current page, but different search params, were not prefetched. diff --git a/packages/astro/e2e/fixtures/prefetch/src/pages/index.astro b/packages/astro/e2e/fixtures/prefetch/src/pages/index.astro index e61bc1c6c33e..88ce196ae22f 100644 --- a/packages/astro/e2e/fixtures/prefetch/src/pages/index.astro +++ b/packages/astro/e2e/fixtures/prefetch/src/pages/index.astro @@ -9,6 +9,8 @@
false
+ search param +
tap
hover diff --git a/packages/astro/e2e/prefetch.test.js b/packages/astro/e2e/prefetch.test.js index dc29bde33f07..a19c87680eca 100644 --- a/packages/astro/e2e/prefetch.test.js +++ b/packages/astro/e2e/prefetch.test.js @@ -16,7 +16,8 @@ test.describe('Prefetch (default)', () => { test.beforeEach(async ({ page }) => { page.on('request', (req) => { - reqUrls.push(new URL(req.url()).pathname); + const urlObj = new URL(req.url()); + reqUrls.push(urlObj.pathname + urlObj.search); }); }); @@ -38,6 +39,16 @@ test.describe('Prefetch (default)', () => { expect(reqUrls).not.toContainEqual('/prefetch-false'); }); + test('Link with search param should prefetch', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/')); + expect(reqUrls).not.toContainEqual('/?search-param=true'); + await Promise.all([ + page.waitForEvent('request'), // wait prefetch request + page.locator('#prefetch-search-param').hover(), + ]); + expect(reqUrls).toContainEqual('/?search-param=true'); + }); + test('data-astro-prefetch="tap" should prefetch on tap', async ({ page, astro }) => { await page.goto(astro.resolveUrl('/')); expect(reqUrls).not.toContainEqual('/prefetch-tap'); @@ -102,7 +113,8 @@ test.describe("Prefetch (prefetchAll: true, defaultStrategy: 'tap')", () => { test.beforeEach(async ({ page }) => { page.on('request', (req) => { - reqUrls.push(new URL(req.url()).pathname); + const urlObj = new URL(req.url()); + reqUrls.push(urlObj.pathname + urlObj.search); }); }); @@ -129,6 +141,16 @@ test.describe("Prefetch (prefetchAll: true, defaultStrategy: 'tap')", () => { expect(reqUrls).not.toContainEqual('/prefetch-false'); }); + test('Link with search param should prefetch', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/')); + expect(reqUrls).not.toContainEqual('/?search-param=true'); + await Promise.all([ + page.waitForEvent('request'), // wait prefetch request + page.locator('#prefetch-search-param').hover(), + ]); + expect(reqUrls).toContainEqual('/?search-param=true'); + }); + test('data-astro-prefetch="tap" should prefetch on tap', async ({ page, astro }) => { await page.goto(astro.resolveUrl('/')); expect(reqUrls).not.toContainEqual('/prefetch-tap'); diff --git a/packages/astro/src/prefetch/index.ts b/packages/astro/src/prefetch/index.ts index 573efe5734ef..15f4ef0ccd95 100644 --- a/packages/astro/src/prefetch/index.ts +++ b/packages/astro/src/prefetch/index.ts @@ -226,7 +226,7 @@ function canPrefetchUrl(url: string, ignoreSlowConnection: boolean) { const urlObj = new URL(url, location.href); return ( location.origin === urlObj.origin && - location.pathname !== urlObj.pathname && + (location.pathname !== urlObj.pathname || location.search !== urlObj.search) && !prefetchedUrls.has(url) ); } catch {}