diff --git a/packages/next/server/base-server.ts b/packages/next/server/base-server.ts index f02f7db199d5..a575e1ad5969 100644 --- a/packages/next/server/base-server.ts +++ b/packages/next/server/base-server.ts @@ -42,7 +42,7 @@ import { import * as envConfig from '../shared/lib/runtime-config' import { DecodeError, normalizeRepeatedSlashes } from '../shared/lib/utils' import { isTargetLikeServerless } from './utils' -import Router, { replaceBasePath, route } from './router' +import Router, { route } from './router' import { setRevalidateHeaders } from './send-payload/revalidate-headers' import { IncrementalCache } from './incremental-cache' import { execOnce } from '../shared/lib/utils' @@ -64,6 +64,7 @@ import { addRequestMeta, getRequestMeta } from './request-meta' import { createHeaderRoute, createRedirectRoute } from './server-route-utils' import { PrerenderManifest } from '../build' import { ImageConfigComplete } from '../shared/lib/image-config' +import { replaceBasePath } from './router-utils' export type FindComponentsResult = { components: LoadComponentsReturnType diff --git a/packages/next/server/dev/next-dev-server.ts b/packages/next/server/dev/next-dev-server.ts index 2a18039e6481..b30545ae5bdc 100644 --- a/packages/next/server/dev/next-dev-server.ts +++ b/packages/next/server/dev/next-dev-server.ts @@ -41,7 +41,8 @@ import { } from '../../shared/lib/router/utils' import Server, { WrappedBuildError } from '../next-server' import { normalizePagePath } from '../normalize-page-path' -import Router, { hasBasePath, replaceBasePath, route } from '../router' +import Router, { route } from '../router' +import { hasBasePath, replaceBasePath } from '../router-utils' import { eventCliSession } from '../../telemetry/events' import { Telemetry } from '../../telemetry/storage' import { setGlobal } from '../../trace' diff --git a/packages/next/server/router-utils.ts b/packages/next/server/router-utils.ts new file mode 100644 index 000000000000..630521434fdb --- /dev/null +++ b/packages/next/server/router-utils.ts @@ -0,0 +1,17 @@ +export function replaceBasePath(pathname: string, basePath: string): string { + // ensure basePath is only stripped if it matches exactly + // and doesn't contain extra chars e.g. basePath /docs + // should replace for /docs, /docs/, /docs/a but not /docsss + if (hasBasePath(pathname, basePath)) { + pathname = pathname.substr(basePath.length) + if (!pathname.startsWith('/')) pathname = `/${pathname}` + } + return pathname +} + +export function hasBasePath(pathname: string, basePath: string): boolean { + return ( + typeof pathname === 'string' && + (pathname === basePath || pathname.startsWith(basePath + '/')) + ) +} diff --git a/packages/next/server/web/next-url.ts b/packages/next/server/web/next-url.ts index 532b93e64ab3..8ceaea68323e 100644 --- a/packages/next/server/web/next-url.ts +++ b/packages/next/server/web/next-url.ts @@ -1,8 +1,8 @@ import type { PathLocale } from '../../shared/lib/i18n/normalize-locale-path' import type { DomainLocale, I18NConfig } from '../config-shared' import { getLocaleMetadata } from '../../shared/lib/i18n/get-locale-metadata' -import { replaceBasePath } from '../router' import cookie from 'next/dist/compiled/cookie' +import { replaceBasePath } from '../router-utils' interface Options { base?: string | URL diff --git a/packages/next/shared/lib/router/utils/parse-next-url.ts b/packages/next/shared/lib/router/utils/parse-next-url.ts index 57985ecfaf0c..0e36e4b6191e 100644 --- a/packages/next/shared/lib/router/utils/parse-next-url.ts +++ b/packages/next/shared/lib/router/utils/parse-next-url.ts @@ -4,7 +4,7 @@ import { parseUrl } from './parse-url' import type { NextConfig, DomainLocale } from '../../../../server/config-shared' import type { ParsedUrl } from './parse-url' import type { PathLocale } from '../../i18n/normalize-locale-path' -import { hasBasePath, replaceBasePath } from '../../../../server/router' +import { hasBasePath, replaceBasePath } from '../../../../server/router-utils' interface Params { headers?: { [key: string]: string | string[] | undefined }