diff --git a/packages/next/src/lib/metadata/resolvers/resolve-url.test.ts b/packages/next/src/lib/metadata/resolvers/resolve-url.test.ts index b9e1caf796aa52..4e57ca6f587f9b 100644 --- a/packages/next/src/lib/metadata/resolvers/resolve-url.test.ts +++ b/packages/next/src/lib/metadata/resolvers/resolve-url.test.ts @@ -110,6 +110,13 @@ describe('resolveAbsoluteUrlWithPathname', () => { 'https://example.com/foo?bar' ) }) + + it('should not add trailing slash to relative url that ends with a file extension', () => { + expect(resolver('/foo.html')).toBe('https://example.com/foo.html') + expect(resolver(new URL('/foo.html', metadataBase))).toBe( + 'https://example.com/foo.html' + ) + }) }) }) diff --git a/packages/next/src/lib/metadata/resolvers/resolve-url.ts b/packages/next/src/lib/metadata/resolvers/resolve-url.ts index 89edce00fa6db2..e4056709549b29 100644 --- a/packages/next/src/lib/metadata/resolvers/resolve-url.ts +++ b/packages/next/src/lib/metadata/resolvers/resolve-url.ts @@ -112,6 +112,8 @@ function resolveAbsoluteUrlWithPathname( let isRelative = resolvedUrl.startsWith('/') let isExternal = false let hasQuery = resolvedUrl.includes('?') + let hasFileExtension = /\.[0-9a-z]+$/i.test(resolvedUrl) + if (!isRelative) { try { const parsedUrl = new URL(resolvedUrl) @@ -121,7 +123,8 @@ function resolveAbsoluteUrlWithPathname( // If it's not a valid URL, treat it as external isExternal = true } - if (!isExternal && !hasQuery) return `${resolvedUrl}/` + if (!hasFileExtension && !isExternal && !hasQuery) + return `${resolvedUrl}/` } }