From 9dcb0060faf367d9c36c7cc011edbe0bb393bd90 Mon Sep 17 00:00:00 2001 From: Kyle Marshall Date: Wed, 21 Apr 2021 14:37:54 -0400 Subject: [PATCH] Ensure locale key is not duplicated when navigating back to root path with a query or hash value --- .../next/next-server/lib/router/router.ts | 3 +- test/integration/i18n-support/test/shared.js | 78 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/packages/next/next-server/lib/router/router.ts b/packages/next/next-server/lib/router/router.ts index 785cbf0bbaf8b..45379d17937d0 100644 --- a/packages/next/next-server/lib/router/router.ts +++ b/packages/next/next-server/lib/router/router.ts @@ -113,7 +113,8 @@ export function addLocale( defaultLocale?: string ) { if (process.env.__NEXT_I18N_SUPPORT) { - const pathLower = path.toLowerCase() + const pathname = pathNoQueryHash(path) + const pathLower = pathname.toLowerCase() const localeLower = locale && locale.toLowerCase() return locale && diff --git a/test/integration/i18n-support/test/shared.js b/test/integration/i18n-support/test/shared.js index f183ee1b9dc0b..f0dac7dafbad3 100644 --- a/test/integration/i18n-support/test/shared.js +++ b/test/integration/i18n-support/test/shared.js @@ -53,6 +53,84 @@ export function runTests(ctx) { expect(await res.text()).toContain('index page') }) + it('should not add duplicate locale key when navigating back to root path with query params', async () => { + const basePath = ctx.basePath || '' + const queryKey = 'query' + const queryValue = '1' + const browser = await webdriver( + ctx.appPort, + `${basePath}/fr?${queryKey}=${queryValue}` + ) + + expect(await browser.eval(() => document.location.pathname)).toBe( + `${basePath}/fr` + ) + expect(await browser.elementByCss('#router-pathname').text()).toBe('/') + expect( + JSON.parse(await browser.elementByCss('#router-query').text()) + ).toEqual({ [queryKey]: queryValue }) + expect(await browser.elementByCss('#router-locale').text()).toBe('fr') + + await browser + .elementByCss('#to-another') + .click() + .waitForElementByCss('#another') + + expect(await browser.eval(() => document.location.pathname)).toBe( + `${basePath}/fr/another` + ) + expect(await browser.elementByCss('#router-pathname').text()).toBe( + '/another' + ) + expect(await browser.elementByCss('#router-locale').text()).toBe('fr') + + await browser.back().waitForElementByCss('#index') + + expect(await browser.eval(() => document.location.pathname)).toBe( + `${basePath}/fr` + ) + expect(await browser.elementByCss('#router-pathname').text()).toBe('/') + expect( + JSON.parse(await browser.elementByCss('#router-query').text()) + ).toEqual({ [queryKey]: queryValue }) + expect(await browser.elementByCss('#router-locale').text()).toBe('fr') + }) + + it('should not add duplicate locale key when navigating back to root path with hash', async () => { + const basePath = ctx.basePath || '' + const hashValue = '#anchor-1' + const browser = await webdriver(ctx.appPort, `${basePath}/fr${hashValue}`) + + expect(await browser.eval(() => document.location.pathname)).toBe( + `${basePath}/fr` + ) + expect(await browser.eval(() => document.location.hash)).toBe(hashValue) + expect(await browser.elementByCss('#router-pathname').text()).toBe('/') + expect(await browser.elementByCss('#router-locale').text()).toBe('fr') + + await browser + .elementByCss('#to-another') + .click() + .waitForElementByCss('#another') + + expect(await browser.eval(() => document.location.pathname)).toBe( + `${basePath}/fr/another` + ) + expect(await browser.elementByCss('#router-pathname').text()).toBe( + '/another' + ) + expect(await browser.elementByCss('#router-locale').text()).toBe('fr') + + await browser.back().waitForElementByCss('#index') + + expect(await browser.eval(() => document.location.pathname)).toBe( + `${basePath}/fr` + ) + expect(await browser.eval(() => document.location.hash)).toBe(hashValue) + expect(await browser.elementByCss('#router-pathname').text()).toBe('/') + expect(await browser.elementByCss('#router-locale').text()).toBe('fr') + }) + it('should handle navigating back to different casing of locale', async () => { const browser = await webdriver( ctx.appPort,