diff --git a/packages/next/shared/lib/router/router.ts b/packages/next/shared/lib/router/router.ts
index 35ef048c771de4d..5e858c1f60b3265 100644
--- a/packages/next/shared/lib/router/router.ts
+++ b/packages/next/shared/lib/router/router.ts
@@ -125,6 +125,11 @@ function addPathPrefix(path: string, prefix?: string) {
)
}
+function hasPathPrefix(path: string, prefix: string) {
+ path = pathNoQueryHash(path)
+ return path === prefix || path.startsWith(prefix + '/')
+}
+
export function getDomainLocale(
path: string,
locale?: string | false,
@@ -153,16 +158,18 @@ export function addLocale(
defaultLocale?: string
) {
if (process.env.__NEXT_I18N_SUPPORT) {
- const pathname = pathNoQueryHash(path)
- const pathLower = pathname.toLowerCase()
- const localeLower = locale && locale.toLowerCase()
+ if (locale && locale !== defaultLocale) {
+ const pathname = pathNoQueryHash(path)
+ const pathLower = pathname.toLowerCase()
+ const localeLower = locale.toLowerCase()
- return locale &&
- locale !== defaultLocale &&
- !pathLower.startsWith('/' + localeLower + '/') &&
- pathLower !== '/' + localeLower
- ? addPathPrefix(path, '/' + locale)
- : path
+ if (
+ !hasPathPrefix(pathLower, '/' + localeLower) &&
+ !hasPathPrefix(pathLower, '/api')
+ ) {
+ return addPathPrefix(path, '/' + locale)
+ }
+ }
}
return path
}
@@ -194,8 +201,7 @@ function pathNoQueryHash(path: string) {
}
export function hasBasePath(path: string): boolean {
- path = pathNoQueryHash(path)
- return path === basePath || path.startsWith(basePath + '/')
+ return hasPathPrefix(path, basePath)
}
export function addBasePath(path: string): string {
diff --git a/test/integration/i18n-support/pages/index.js b/test/integration/i18n-support/pages/index.js
index ec72e72258857b0..37891aa406f7731 100644
--- a/test/integration/i18n-support/pages/index.js
+++ b/test/integration/i18n-support/pages/index.js
@@ -47,6 +47,10 @@ export default function Page(props) {
to /gssp/first
+
+ to /api/post/[slug]
+
+
>
)
}
diff --git a/test/integration/i18n-support/test/index.test.js b/test/integration/i18n-support/test/index.test.js
index 87190ab5877d3e4..96a371db5ea39b5 100644
--- a/test/integration/i18n-support/test/index.test.js
+++ b/test/integration/i18n-support/test/index.test.js
@@ -495,6 +495,16 @@ describe('i18n Support', () => {
expect(await browser.eval('window.location.pathname')).toBe(
`${localePath}gssp/first/`
)
+
+ await browser.back().waitForElementByCss('#index')
+ await browser.elementByCss('#to-api-post').click()
+
+ await browser.waitForCondition(
+ 'window.location.pathname === "/api/post/asdf/"'
+ )
+ const body = await browser.elementByCss('body').text()
+ const json = JSON.parse(body)
+ expect(json.post).toBe(true)
}
})
}
diff --git a/test/integration/middleware/core/pages/api/ok.js b/test/integration/middleware/core/pages/api/ok.js
new file mode 100644
index 000000000000000..fb91e8b61140961
--- /dev/null
+++ b/test/integration/middleware/core/pages/api/ok.js
@@ -0,0 +1,3 @@
+export default function handler(req, res) {
+ res.send('ok')
+}
diff --git a/test/integration/middleware/core/pages/redirects/_middleware.js b/test/integration/middleware/core/pages/redirects/_middleware.js
index 0a8dafc5c8b262d..2e54cf550fb755d 100644
--- a/test/integration/middleware/core/pages/redirects/_middleware.js
+++ b/test/integration/middleware/core/pages/redirects/_middleware.js
@@ -58,4 +58,10 @@ export async function middleware(request) {
url.pathname = '/redirects/infinite-loop'
return Response.redirect(url)
}
+
+ if (url.pathname === '/redirects/to') {
+ url.pathname = url.searchParams.get('pathname')
+ url.searchParams.delete('pathname')
+ return Response.redirect(url)
+ }
}
diff --git a/test/integration/middleware/core/pages/redirects/index.js b/test/integration/middleware/core/pages/redirects/index.js
index 735e73d232bc32e..f1a9a1e193ad944 100644
--- a/test/integration/middleware/core/pages/redirects/index.js
+++ b/test/integration/middleware/core/pages/redirects/index.js
@@ -28,6 +28,10 @@ export default function Home() {
Redirect me alot (infinite loop)