Skip to content

Commit

Permalink
Bug fix: Order of params for routing has to match (withastro#2593)
Browse files Browse the repository at this point in the history
* make sure route params are sorted before comparing stringified keys

* including changeset for a patch release
  • Loading branch information
Tony Sullivan committed Feb 16, 2022
1 parent b4dcc0f commit 40c0e2b
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/sweet-spoons-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Dynamic route params should ignore param order when matching paths
3 changes: 1 addition & 2 deletions packages/astro/src/core/render/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ async function getParamsAndProps(opts: GetParamsAndPropsOptions): Promise<[Param
routeCacheEntry = await callGetStaticPaths(mod, route, true, logging);
routeCache.set(route, routeCacheEntry);
}
const paramsKey = JSON.stringify(params);
const matchedStaticPath = findPathItemByKey(routeCacheEntry.staticPaths, paramsKey);
const matchedStaticPath = findPathItemByKey(routeCacheEntry.staticPaths, params);
if (!matchedStaticPath) {
throw new Error(`[getStaticPaths] route pattern matched, but no matching static path found. (${pathname})`);
}
Expand Down
12 changes: 9 additions & 3 deletions packages/astro/src/core/render/route-cache.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import type { ComponentInstance, GetStaticPathsItem, GetStaticPathsResult, GetStaticPathsResultKeyed, RouteData, RSS } from '../../@types/astro';
import type { ComponentInstance, GetStaticPathsItem, GetStaticPathsResult, GetStaticPathsResultKeyed, Params, RouteData, RSS } from '../../@types/astro';
import { LogOptions, warn, debug } from '../logger.js';

import { generatePaginateFunction } from './paginate.js';
import { validateGetStaticPathsModule, validateGetStaticPathsResult } from '../routing/index.js';

type RSSFn = (...args: any[]) => any;

function stringifyParams(params: Params) {
// Always sort keys before stringifying to make sure objects match regardless of parameter ordering
return JSON.stringify(params, Object.keys(params).sort());
}

export async function callGetStaticPaths(mod: ComponentInstance, route: RouteData, isValidate: boolean, logging: LogOptions): Promise<RouteCacheEntry> {
validateGetStaticPathsModule(mod);
const resultInProgress = {
Expand All @@ -23,7 +28,7 @@ export async function callGetStaticPaths(mod: ComponentInstance, route: RouteDat
const keyedStaticPaths = staticPaths as GetStaticPathsResultKeyed;
keyedStaticPaths.keyed = new Map<string, GetStaticPathsItem>();
for (const sp of keyedStaticPaths) {
const paramsKey = JSON.stringify(sp.params);
const paramsKey = stringifyParams(sp.params);
keyedStaticPaths.keyed.set(paramsKey, sp);
}
if (isValidate) {
Expand Down Expand Up @@ -73,7 +78,8 @@ export class RouteCache {
}
}

export function findPathItemByKey(staticPaths: GetStaticPathsResultKeyed, paramsKey: string) {
export function findPathItemByKey(staticPaths: GetStaticPathsResultKeyed, params: Params) {
const paramsKey = stringifyParams(params);
let matchedStaticPath = staticPaths.keyed.get(paramsKey);
if (matchedStaticPath) {
return matchedStaticPath;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
export async function getStaticPaths() {
return [
{ params: { year: '2022', slug: 'post-1' } },
{ params: { slug: 'post-2', year: '2022' } },
]
}
const { year, slug } = Astro.request.params
---

<html>
<head>
<title>{year} | {slug}</title>
</head>
<body></body>
</html>

0 comments on commit 40c0e2b

Please sign in to comment.