rsnext/packages/next/next-server/lib/router/utils/resolve-rewrites.ts
JJ Kasper 42385f48db
Ensure i18n custom routes resolves correctly (#19766)
This ensures i81n custom routes are resolving correctly, it also corrects redirects for default locales when `locale: false` is not used, and this also simplifies the resolving for custom routes with i18n in `next-server` adding types for the i18n config. This also adds additional tests to prevent regression and starts leveraging a shared `NextConfig` type to allow us to share types for config values. 

Fixes: https://github.com/vercel/next.js/issues/19521
Fixes: https://github.com/vercel/next.js/issues/19403
Fixes: https://github.com/vercel/next.js/issues/19302
Fixes: https://github.com/vercel/next.js/issues/19227
2020-12-04 10:14:55 +00:00

60 lines
1.8 KiB
TypeScript

import { ParsedUrlQuery } from 'querystring'
import pathMatch from './path-match'
import prepareDestination from './prepare-destination'
import { Rewrite } from '../../../../lib/load-custom-routes'
import { removePathTrailingSlash } from '../../../../client/normalize-trailing-slash'
import { normalizeLocalePath } from '../../i18n/normalize-locale-path'
const customRouteMatcher = pathMatch(true)
export default function resolveRewrites(
asPath: string,
pages: string[],
rewrites: Rewrite[],
query: ParsedUrlQuery,
resolveHref: (path: string) => string,
locales?: string[]
) {
if (!pages.includes(normalizeLocalePath(asPath, locales).pathname)) {
for (const rewrite of rewrites) {
const matcher = customRouteMatcher(rewrite.source)
const params = matcher(asPath)
if (params) {
if (!rewrite.destination) {
// this is a proxied rewrite which isn't handled on the client
break
}
const destRes = prepareDestination(
rewrite.destination,
params,
query,
true
)
asPath = destRes.parsedDestination.pathname!
Object.assign(query, destRes.parsedDestination.query)
const fsPathname = normalizeLocalePath(
removePathTrailingSlash(asPath),
locales
).pathname
if (pages.includes(fsPathname)) {
asPath = fsPathname
// check if we now match a page as this means we are done
// resolving the rewrites
break
}
// check if we match a dynamic-route, if so we break the rewrites chain
const resolvedHref = resolveHref(fsPathname)
if (resolvedHref !== asPath && pages.includes(resolvedHref)) {
asPath = fsPathname
break
}
}
}
}
return asPath
}