diff --git a/packages/next/shared/lib/router/router.ts b/packages/next/shared/lib/router/router.ts index 2816ab180e804a..7c78d209082177 100644 --- a/packages/next/shared/lib/router/router.ts +++ b/packages/next/shared/lib/router/router.ts @@ -214,10 +214,14 @@ export function delBasePath(path: string): string { */ export function isLocalURL(url: string): boolean { // prevent a hydration mismatch on href for url with anchor refs - if (url.startsWith('/') || url.startsWith('#') || url.startsWith('?')) + if ( + url.match(/^\/(?!\/)/) !== null || + url.startsWith('#') || + url.startsWith('?') + ) return true try { - // absolute urls can be local if they are on the same origin + // absolute and scheme-relative urls can be local if they are on the same origin const locationOrigin = getLocationOrigin() const resolved = new URL(url, locationOrigin) return resolved.origin === locationOrigin && hasBasePath(resolved.pathname) @@ -318,9 +322,9 @@ export function resolveHref( // repeated slashes and backslashes in the URL are considered // invalid and will never match a Next.js page/file - const urlProtoMatch = urlAsString.match(/^[a-zA-Z]{1,}:\/\//) - const urlAsStringNoProto = urlProtoMatch - ? urlAsString.slice(urlProtoMatch[0].length) + const urlSchemeMatch = urlAsString.match(/^(?:[a-zA-Z]+:)?\/\//) + const urlAsStringNoProto = urlSchemeMatch + ? urlAsString.slice(urlSchemeMatch[0].length) : urlAsString const urlParts = urlAsStringNoProto.split('?') @@ -330,7 +334,7 @@ export function resolveHref( `Invalid href passed to next/router: ${urlAsString}, repeated forward-slashes (//) or backslashes \\ are not valid in the href` ) const normalizedUrl = normalizeRepeatedSlashes(urlAsStringNoProto) - urlAsString = (urlProtoMatch ? urlProtoMatch[0] : '') + normalizedUrl + urlAsString = (urlSchemeMatch ? urlSchemeMatch[0] : '') + normalizedUrl } // Return because it cannot be routed by the Next.js router diff --git a/test/integration/repeated-slashes/app/pages/invalid.js b/test/integration/repeated-slashes/app/pages/invalid.js index 907fd59f457a43..8586781ca2f791 100644 --- a/test/integration/repeated-slashes/app/pages/invalid.js +++ b/test/integration/repeated-slashes/app/pages/invalid.js @@ -14,43 +14,47 @@ export default function Invalid() { return ( <>
invalid page
- - to /another as //google.com + + to /another as /google.com//maps