fix: add decoding logic to app router params (#18712)

* decode app router params in buildLegacyCtx

* add helpful comments

* add comment

* address comment
This commit is contained in:
Benny Joo
2025-01-16 15:14:03 +00:00
committed by GitHub
parent b7f7c33afc
commit c37a8a587b
3 changed files with 27 additions and 2 deletions
+23 -1
View File
@@ -26,6 +26,25 @@ const buildLegacyCookies = (cookies: ReadonlyRequestCookies) => {
return createProxifiedObject(cookiesObject);
};
function decodeParams(params: Params): Params {
return Object.entries(params).reduce((acc, [key, value]) => {
// Handle array values
if (Array.isArray(value)) {
acc[key] = value.map((item) => decodeURIComponent(item));
return acc;
}
// Handle single values
if (value !== undefined) {
acc[key] = decodeURIComponent(value);
} else {
acc[key] = value;
}
return acc;
}, {} as Params);
}
export const buildLegacyCtx = (
headers: ReadonlyHeaders,
cookies: ReadonlyRequestCookies,
@@ -34,7 +53,10 @@ export const buildLegacyCtx = (
) => {
return {
query: { ...searchParams, ...params },
params,
// decoding is required to be backward compatible with Pages Router
// because Next.js App Router does not auto-decode query params while Pages Router does
// e.g., params: { name: "John%20Doe" } => params: { name: "John Doe" }
params: decodeParams(params),
req: { headers: buildLegacyHeaders(headers), cookies: buildLegacyCookies(cookies) },
res: new Proxy(Object.create(null), {
// const { req, res } = ctx - valid
@@ -106,6 +106,9 @@ export const getServerSideProps: GetServerSideProps<UserPageProps> = async (cont
if (isDynamicGroup) {
const destinationUrl = `/${usernameList.join("+")}/dynamic`;
// EXAMPLE - context.params: { orgSlug: 'acme', user: 'member0+owner1' }
// EXAMPLE - context.query: { redirect: 'undefined', orgRedirection: 'undefined', user: 'member0+owner1' }
const originalQueryString = new URLSearchParams(context.query as Record<string, string>).toString();
const destinationWithQuery = `${destinationUrl}?${originalQueryString}`;
log.debug(`Dynamic group detected, redirecting to ${destinationUrl}`);
+1 -1
View File
@@ -178,7 +178,7 @@ export const getUsernameList = (users: string | string[] | undefined): string[]
// So, even though this code handles even if individual user is dynamic link, that isn't a possibility right now.
users = arrayCast(users);
const allUsers = users.map((user) => user.replace(/( |%20|%2b)/g, "+").split("+")).flat();
const allUsers = users.map((user) => user.replace(/( |%20|%2b)/gi, "+").split("+")).flat();
return Array.prototype.concat(...allUsers.map((userSlug) => slugify(userSlug)));
};