diff --git a/.changeset/famous-numbers-smell.md b/.changeset/famous-numbers-smell.md new file mode 100644 index 000000000000..be778992a417 --- /dev/null +++ b/.changeset/famous-numbers-smell.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixed an issue where configured redirects with dynamic routes did not work in dev mode. diff --git a/packages/astro/src/core/render/params-and-props.ts b/packages/astro/src/core/render/params-and-props.ts index 6cdb05ed11af..8c75e75e2aa3 100644 --- a/packages/astro/src/core/render/params-and-props.ts +++ b/packages/astro/src/core/render/params-and-props.ts @@ -1,6 +1,7 @@ import type { ComponentInstance, Params, Props, RouteData } from '../../@types/astro.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; import type { Logger } from '../logger/core.js'; +import { routeIsRedirect } from '../redirects/index.js'; import { getParams } from '../routing/params.js'; import { RouteCache, callGetStaticPaths, findPathItemByKey } from './route-cache.js'; @@ -25,6 +26,10 @@ export async function getParamsAndProps(opts: GetParamsAndPropsOptions): Promise // This is a dynamic route, start getting the params const params = getRouteParams(route, pathname) ?? {}; + if (routeIsRedirect(route)) { + return [params, {}] + } + validatePrerenderEndpointCollision(route, mod, params); // During build, the route cache should already be populated. diff --git a/packages/astro/test/fixtures/ssr-redirect/package.json b/packages/astro/test/fixtures/redirects/package.json similarity index 100% rename from packages/astro/test/fixtures/ssr-redirect/package.json rename to packages/astro/test/fixtures/redirects/package.json diff --git a/packages/astro/test/fixtures/ssr-redirect/src/components/redirect.astro b/packages/astro/test/fixtures/redirects/src/components/redirect.astro similarity index 100% rename from packages/astro/test/fixtures/ssr-redirect/src/components/redirect.astro rename to packages/astro/test/fixtures/redirects/src/components/redirect.astro diff --git a/packages/astro/test/fixtures/ssr-redirect/src/middleware.ts b/packages/astro/test/fixtures/redirects/src/middleware.ts similarity index 100% rename from packages/astro/test/fixtures/ssr-redirect/src/middleware.ts rename to packages/astro/test/fixtures/redirects/src/middleware.ts diff --git a/packages/astro/test/fixtures/ssr-redirect/src/pages/articles/[...slug].astro b/packages/astro/test/fixtures/redirects/src/pages/articles/[...slug].astro similarity index 100% rename from packages/astro/test/fixtures/ssr-redirect/src/pages/articles/[...slug].astro rename to packages/astro/test/fixtures/redirects/src/pages/articles/[...slug].astro diff --git a/packages/astro/test/fixtures/ssr-redirect/src/pages/late.astro b/packages/astro/test/fixtures/redirects/src/pages/late.astro similarity index 100% rename from packages/astro/test/fixtures/ssr-redirect/src/pages/late.astro rename to packages/astro/test/fixtures/redirects/src/pages/late.astro diff --git a/packages/astro/test/fixtures/ssr-redirect/src/pages/middleware-redirect.astro b/packages/astro/test/fixtures/redirects/src/pages/middleware-redirect.astro similarity index 100% rename from packages/astro/test/fixtures/ssr-redirect/src/pages/middleware-redirect.astro rename to packages/astro/test/fixtures/redirects/src/pages/middleware-redirect.astro diff --git a/packages/astro/test/fixtures/redirects/src/pages/more/[dynamic].astro b/packages/astro/test/fixtures/redirects/src/pages/more/[dynamic].astro new file mode 100644 index 000000000000..f980c25baa68 --- /dev/null +++ b/packages/astro/test/fixtures/redirects/src/pages/more/[dynamic].astro @@ -0,0 +1,8 @@ +--- +export function getStaticPaths() { + return [{ params: { dynamic:'hello' } }] +} +--- +{JSON.stringify(Astro.params)} + +home \ No newline at end of file diff --git a/packages/astro/test/fixtures/redirects/src/pages/more/[dynamic]/[route].astro b/packages/astro/test/fixtures/redirects/src/pages/more/[dynamic]/[route].astro new file mode 100644 index 000000000000..94ccb545ff9b --- /dev/null +++ b/packages/astro/test/fixtures/redirects/src/pages/more/[dynamic]/[route].astro @@ -0,0 +1,8 @@ +--- +export function getStaticPaths() { + return [{ params: { dynamic:'hello', route:'world' } }] +} +--- +{JSON.stringify(Astro.params)} + +home diff --git a/packages/astro/test/fixtures/redirects/src/pages/more/new/[...spread].astro b/packages/astro/test/fixtures/redirects/src/pages/more/new/[...spread].astro new file mode 100644 index 000000000000..f34bb28f64a8 --- /dev/null +++ b/packages/astro/test/fixtures/redirects/src/pages/more/new/[...spread].astro @@ -0,0 +1,8 @@ +--- +export function getStaticPaths() { + return [{ params: {spread:'welcome/world'} }] +} +--- +{JSON.stringify(Astro.params)} + +home \ No newline at end of file diff --git a/packages/astro/test/fixtures/ssr-redirect/src/pages/secret.astro b/packages/astro/test/fixtures/redirects/src/pages/secret.astro similarity index 100% rename from packages/astro/test/fixtures/ssr-redirect/src/pages/secret.astro rename to packages/astro/test/fixtures/redirects/src/pages/secret.astro diff --git a/packages/astro/test/fixtures/ssr-redirect/src/pages/test.astro b/packages/astro/test/fixtures/redirects/src/pages/test.astro similarity index 100% rename from packages/astro/test/fixtures/ssr-redirect/src/pages/test.astro rename to packages/astro/test/fixtures/redirects/src/pages/test.astro diff --git a/packages/astro/test/redirects.test.js b/packages/astro/test/redirects.test.js index 999ab1f0f3ed..a5a06530935e 100644 --- a/packages/astro/test/redirects.test.js +++ b/packages/astro/test/redirects.test.js @@ -9,7 +9,7 @@ describe('Astro.redirect', () => { describe('output: "server"', () => { before(async () => { fixture = await loadFixture({ - root: './fixtures/ssr-redirect/', + root: './fixtures/redirects/', output: 'server', adapter: testAdapter(), redirects: { @@ -66,7 +66,7 @@ describe('Astro.redirect', () => { before(async () => { process.env.STATIC_MODE = true; fixture = await loadFixture({ - root: './fixtures/ssr-redirect/', + root: './fixtures/redirects/', output: 'static', redirects: { '/old': '/test', @@ -78,6 +78,9 @@ describe('Astro.redirect', () => { status: 302, destination: '/test', }, + '/more/old/[dynamic]': '/more/[dynamic]', + '/more/old/[dynamic]/[route]': '/more/[dynamic]/[route]', + '/more/old/[...spread]': '/more/new/[...spread]', }, }); await fixture.build(); @@ -149,6 +152,12 @@ describe('Astro.redirect', () => { expect(html).to.include('http-equiv="refresh'); expect(html).to.include('url=/test'); }); + + it('falls back to spread rule when dynamic rules should not match', async () => { + const html = await fixture.readFile('/more/old/welcome/world/index.html'); + expect(html).to.include('http-equiv="refresh'); + expect(html).to.include('url=/more/new/welcome/world'); + }); }); describe('dev', () => { @@ -157,10 +166,13 @@ describe('Astro.redirect', () => { before(async () => { process.env.STATIC_MODE = true; fixture = await loadFixture({ - root: './fixtures/ssr-redirect/', + root: './fixtures/redirects/', output: 'static', redirects: { '/one': '/', + '/more/old/[dynamic]': '/more/[dynamic]', + '/more/old/[dynamic]/[route]': '/more/[dynamic]/[route]', + '/more/old/[...spread]': '/more/new/[...spread]', }, }); devServer = await fixture.startDevServer(); @@ -170,11 +182,27 @@ describe('Astro.redirect', () => { await devServer.stop(); }); - it('Returns 301', async () => { + it('performs simple redirects', async () => { let res = await fixture.fetch('/one', { redirect: 'manual', }); expect(res.status).to.equal(301); + expect(res.headers.get('Location')).to.equal('/'); + }); + + it('performs dynamic redirects', async () => { + const response = await fixture.fetch('/more/old/hello', { redirect: 'manual' }); + expect(response.headers.get('Location')).to.equal('/more/hello'); + }); + + it('performs dynamic redirects with multiple params', async () => { + const response = await fixture.fetch('/more/old/hello/world', { redirect: 'manual' }); + expect(response.headers.get('Location')).to.equal('/more/hello/world'); + }); + + it.skip('falls back to spread rule when dynamic rules should not match', async () => { + const response = await fixture.fetch('/more/old/welcome/world', { redirect: 'manual' }); + expect(response.headers.get('Location')).to.equal('/more/new/welcome/world'); }); }); }); @@ -183,7 +211,7 @@ describe('Astro.redirect', () => { before(async () => { process.env.STATIC_MODE = true; fixture = await loadFixture({ - root: './fixtures/ssr-redirect/', + root: './fixtures/redirects/', output: 'static', redirects: { '/one': '/', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 28fd2f162137..addc09144fc9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3054,6 +3054,12 @@ importers: specifier: workspace:* version: link:../../.. + packages/astro/test/fixtures/redirects: + dependencies: + astro: + specifier: workspace:* + version: link:../../.. + packages/astro/test/fixtures/reexport-astro-containing-client-component: dependencies: '@astrojs/preact': @@ -3339,12 +3345,6 @@ importers: specifier: workspace:* version: link:../../.. - packages/astro/test/fixtures/ssr-redirect: - dependencies: - astro: - specifier: workspace:* - version: link:../../.. - packages/astro/test/fixtures/ssr-request: dependencies: astro: