diff --git a/.changeset/witty-grapes-jam.md b/.changeset/witty-grapes-jam.md new file mode 100644 index 000000000000..c3da491cfe03 --- /dev/null +++ b/.changeset/witty-grapes-jam.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fix edge case with file-based routing match logic diff --git a/packages/astro/src/core/render/core.ts b/packages/astro/src/core/render/core.ts index 282c78f2b903..219922b6d5c1 100644 --- a/packages/astro/src/core/render/core.ts +++ b/packages/astro/src/core/render/core.ts @@ -8,7 +8,7 @@ import { getParams } from '../routing/params.js'; import type { RenderContext } from './context.js'; import type { Environment } from './environment.js'; import { createResult } from './result.js'; -import { callGetStaticPaths, findPathItemByKey, RouteCache } from './route-cache.js'; +import { callGetStaticPaths, findPathItemByKey, RouteCache, isEqualRoute } from './route-cache.js'; interface GetParamsAndPropsOptions { mod: ComponentInstance; @@ -89,6 +89,12 @@ export async function getParamsAndProps( routeCacheEntry = await callGetStaticPaths({ mod, route, isValidate: true, logging, ssr }); routeCache.set(route, routeCacheEntry); } + // related to https://github.com/withastro/astro/issues/6968 + const state = isEqualRoute(routeCacheEntry.staticPaths, route, pathname); + if (state !== undefined) { + params = state; + } + const matchedStaticPath = findPathItemByKey(routeCacheEntry.staticPaths, params, route); if (!matchedStaticPath && (ssr ? route.prerender : true)) { return GetParamsAndPropsError.NoMatchingStaticPath; diff --git a/packages/astro/src/core/render/route-cache.ts b/packages/astro/src/core/render/route-cache.ts index 227928267dae..9ddbb71a94f9 100644 --- a/packages/astro/src/core/render/route-cache.ts +++ b/packages/astro/src/core/render/route-cache.ts @@ -126,3 +126,47 @@ export function findPathItemByKey( } debug('findPathItemByKey', `Unexpected cache miss looking for ${paramsKey}`); } + +// the regular expression to match it such as 'example-[foo]-[bar]' and {params: {foo: 'hell-no', bar: 'world2'}} +// I spliced the routing and then compared +export function isEqualRoute( + staticPaths: GetStaticPathsResultKeyed, + route: RouteData, + pathname: string +): Params | undefined { + for (let index = 0; index < staticPaths.length; index++) { + const arg = staticPaths[index]; + let substr = ''; + if (arg.params) { + route?.segments.forEach((segs) => { + substr += '/'; + segs?.forEach((seg) => { + if (!seg.dynamic) { + substr += seg.content; + } else { + // such as ...slug + if (seg.content.startsWith('...')) { + substr += arg.params[seg.content.slice(3)]; + } else { + substr += arg.params[seg.content]; + } + } + }); + }); + if (pathname.endsWith(substr)) { + const params = Object.keys(arg.params as Params); + // related to routing-priority.test.js /empty-slug/undefined + // if the params is undefined, it will be 'undefined' + return params.reduce((obj, key: string) => { + if (arg.params?.[key] === undefined) { + obj[key] = 'undefined'; + } else { + obj[key] = arg.params[key] as string; + } + return obj; + }, {} as Params); + } + } + } + return; +} diff --git a/packages/astro/test/astro-get-static-paths.test.js b/packages/astro/test/astro-get-static-paths.test.js index 6294e1926bf6..306338d86aea 100644 --- a/packages/astro/test/astro-get-static-paths.test.js +++ b/packages/astro/test/astro-get-static-paths.test.js @@ -122,4 +122,8 @@ describe('getStaticPaths - dev calls', () => { ); } }); + it('Validation regularity loopholes', async () => { + let res = await fixture.fetch(`/test/example-hell-no-world2`); + expect(res.status).to.equal(200); + }) }); diff --git a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/test/example-[foo]-[bar].astro b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/test/example-[foo]-[bar].astro new file mode 100644 index 000000000000..9b2b76e57144 --- /dev/null +++ b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/test/example-[foo]-[bar].astro @@ -0,0 +1,21 @@ +--- +export function getStaticPaths() { + return [ + {params: {foo: 'hell-no', bar: 'world2'}} + ]; +} +--- + + + + + + Astro + + +

Reproduction page

+

+ 11 +

+ +