diff --git a/.changeset/ten-parrots-burn.md b/.changeset/ten-parrots-burn.md new file mode 100644 index 000000000..71d3184ff --- /dev/null +++ b/.changeset/ten-parrots-burn.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Treat same pathname with different search params as different page diff --git a/packages/astro/components/ViewTransitions.astro b/packages/astro/components/ViewTransitions.astro index efda3b575..8e233d182 100644 --- a/packages/astro/components/ViewTransitions.astro +++ b/packages/astro/components/ViewTransitions.astro @@ -263,7 +263,11 @@ const { fallback = 'animate' } = Astro.props as Props; link.href && (!link.target || link.target === '_self') && link.origin === location.origin && - location.pathname !== link.pathname && + !( + // Same page means same path and same query params + location.pathname === link.pathname && + location.search === link.search + ) && ev.button === 0 && // left clicks only !ev.metaKey && // new tab (mac) !ev.ctrlKey && // new tab (windows) diff --git a/packages/astro/e2e/fixtures/view-transitions/astro.config.mjs b/packages/astro/e2e/fixtures/view-transitions/astro.config.mjs index c0df0074c..8a9f43bcc 100644 --- a/packages/astro/e2e/fixtures/view-transitions/astro.config.mjs +++ b/packages/astro/e2e/fixtures/view-transitions/astro.config.mjs @@ -1,8 +1,11 @@ import { defineConfig } from 'astro/config'; import react from '@astrojs/react'; +import nodejs from '@astrojs/node'; // https://astro.build/config export default defineConfig({ + output: 'server', + adapter: nodejs({ mode: 'standalone' }), integrations: [react()], experimental: { viewTransitions: true, diff --git a/packages/astro/e2e/fixtures/view-transitions/package.json b/packages/astro/e2e/fixtures/view-transitions/package.json index 90a07f839..f4ba9b17b 100644 --- a/packages/astro/e2e/fixtures/view-transitions/package.json +++ b/packages/astro/e2e/fixtures/view-transitions/package.json @@ -4,6 +4,7 @@ "private": true, "dependencies": { "astro": "workspace:*", + "@astrojs/node": "workspace:*", "@astrojs/react": "workspace:*", "react": "^18.1.0", "react-dom": "^18.1.0" diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/query.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/query.astro new file mode 100644 index 000000000..44dd03ce0 --- /dev/null +++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/query.astro @@ -0,0 +1,9 @@ +--- +import Layout from '../components/Layout.astro'; + +const page = Astro.url.searchParams.get('page') || 1; +--- + +

Page {page}

+ go to 2 +
diff --git a/packages/astro/e2e/view-transitions.test.js b/packages/astro/e2e/view-transitions.test.js index 0a3235b90..d9425118d 100644 --- a/packages/astro/e2e/view-transitions.test.js +++ b/packages/astro/e2e/view-transitions.test.js @@ -294,4 +294,24 @@ test.describe('View Transitions', () => { const meta = page.locator('[name="script-executions"]'); await expect(meta).toHaveAttribute('content', '0'); }); + + test('Navigating to the same path but with different query params should result in transition', async ({ page, astro }) => { + const loads = []; + page.addListener('load', (p) => { + loads.push(p.title()); + }); + + // Go to page 1 + await page.goto(astro.resolveUrl('/query')); + let p = page.locator('#query-page'); + await expect(p, 'should have content').toHaveText('Page 1'); + + // go to page 2 + await page.click('#click-two'); + p = page.locator('#query-page'); + await expect(p, 'should have content').toHaveText('Page 2'); + + + await expect(loads.length, 'There should only be 1 page load').toEqual(1); + }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f240e8340..4dc68b7fe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1484,6 +1484,9 @@ importers: packages/astro/e2e/fixtures/view-transitions: dependencies: + '@astrojs/node': + specifier: workspace:* + version: link:../../../../integrations/node '@astrojs/react': specifier: workspace:* version: link:../../../../integrations/react