diff --git a/packages/next/build/webpack/loaders/next-serverless-loader/utils.ts b/packages/next/build/webpack/loaders/next-serverless-loader/utils.ts index 77ba088a4f25d..c1973f7341eaf 100644 --- a/packages/next/build/webpack/loaders/next-serverless-loader/utils.ts +++ b/packages/next/build/webpack/loaders/next-serverless-loader/utils.ts @@ -29,6 +29,7 @@ import cookie from 'next/dist/compiled/cookie' import { TEMPORARY_REDIRECT_STATUS } from '../../../../shared/lib/constants' import { addRequestMeta } from '../../../../server/request-meta' import { removeTrailingSlash } from '../../../../shared/lib/router/utils/remove-trailing-slash' +import { normalizeRscPath } from '../../../../shared/lib/router/utils/app-paths' export const vercelHeader = 'x-vercel-id' @@ -366,6 +367,18 @@ export function getUtils({ params = Object.keys(defaultRouteRegex.groups).reduce((prev, key) => { let value: string | string[] | undefined = params[key] + if (typeof value === 'string') { + value = normalizeRscPath(value, true) + } + if (Array.isArray(value)) { + value = value.map((val) => { + if (typeof val === 'string') { + val = normalizeRscPath(val, true) + } + return val + }) + } + // if the value matches the default value we can't rely // on the parsed params, this is used to signal if we need // to parse x-now-route-matches or not diff --git a/packages/next/server/base-server.ts b/packages/next/server/base-server.ts index 8c03b09b1c298..66e4d5de9044d 100644 --- a/packages/next/server/base-server.ts +++ b/packages/next/server/base-server.ts @@ -64,7 +64,10 @@ import { addRequestMeta, getRequestMeta } from './request-meta' import { ImageConfigComplete } from '../shared/lib/image-config' import { removePathPrefix } from '../shared/lib/router/utils/remove-path-prefix' -import { normalizeAppPath } from '../shared/lib/router/utils/app-paths' +import { + normalizeAppPath, + normalizeRscPath, +} from '../shared/lib/router/utils/app-paths' import { getRouteMatcher } from '../shared/lib/router/utils/route-matcher' import { getRouteRegex } from '../shared/lib/router/utils/route-regex' import { getHostname } from '../shared/lib/get-hostname' @@ -495,6 +498,11 @@ export default abstract class Server { if (typeof parsedUrl.query === 'string') { parsedUrl.query = parseQs(parsedUrl.query) } + req.url = normalizeRscPath(req.url, this.hasAppDir) + parsedUrl.pathname = normalizeRscPath( + parsedUrl.pathname || '', + this.hasAppDir + ) this.attachRequestMeta(req, parsedUrl) @@ -525,10 +533,10 @@ export default abstract class Server { try { // x-matched-path is the source of truth, it tells what page // should be rendered because we don't process rewrites in minimalMode - let matchedPath = new URL( - req.headers['x-matched-path'], - 'http://localhost' - ).pathname + let matchedPath = normalizeRscPath( + new URL(req.headers['x-matched-path'], 'http://localhost').pathname, + this.hasAppDir + ) let urlPathname = new URL(req.url, 'http://localhost').pathname diff --git a/packages/next/server/web/adapter.ts b/packages/next/server/web/adapter.ts index da29df6450fd4..ddd8213f9906e 100644 --- a/packages/next/server/web/adapter.ts +++ b/packages/next/server/web/adapter.ts @@ -9,6 +9,7 @@ import { relativizeURL } from '../../shared/lib/router/utils/relativize-url' import { waitUntilSymbol } from './spec-extension/fetch-event' import { NextURL } from './next-url' import { stripInternalSearchParams } from '../internal-utils' +import { normalizeRscPath } from '../../shared/lib/router/utils/app-paths' class NextRequestHint extends NextRequest { sourcePage: string @@ -49,6 +50,8 @@ export async function adapter(params: { // TODO-APP: use explicit marker for this const isEdgeRendering = typeof self.__BUILD_MANIFEST !== 'undefined' + params.request.url = normalizeRscPath(params.request.url, true) + const requestUrl = new NextURL(params.request.url, { headers: params.request.headers, nextConfig: params.request.nextConfig, diff --git a/packages/next/shared/lib/router/utils/app-paths.ts b/packages/next/shared/lib/router/utils/app-paths.ts index f48b324d1a6c2..3488d11e9300d 100644 --- a/packages/next/shared/lib/router/utils/app-paths.ts +++ b/packages/next/shared/lib/router/utils/app-paths.ts @@ -21,3 +21,7 @@ export function normalizeAppPath(pathname: string) { return acc + `/${segment}` }, '') } + +export function normalizeRscPath(pathname: string, enabled?: boolean) { + return enabled ? pathname.replace(/\.rsc($|\?)/, '') : pathname +}