Skip to content

Commit

Permalink
Make sure locale detecting is case-insensitive (#17757)
Browse files Browse the repository at this point in the history
Follow-up to #17370 this makes sure the locale detection is case-insensitive.
  • Loading branch information
ijjk committed Oct 11, 2020
1 parent 22f91bb commit 1eeac4f
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 15 deletions.
4 changes: 2 additions & 2 deletions packages/next/build/webpack/loaders/next-serverless-loader.ts
Expand Up @@ -241,10 +241,10 @@ const nextServerlessLoader: loader.Loader = function () {
}
const denormalizedPagePath = denormalizePagePath(parsedUrl.pathname || '/')
const detectedDefaultLocale = !detectedLocale || detectedLocale === defaultLocale
const detectedDefaultLocale = !detectedLocale || detectedLocale.toLowerCase() === defaultLocale.toLowerCase()
const shouldStripDefaultLocale =
detectedDefaultLocale &&
denormalizedPagePath === \`/\${defaultLocale}\`
denormalizedPagePath.toLowerCase() === \`/\${defaultLocale.toLowerCase()}\`
const shouldAddLocalePrefix =
!detectedDefaultLocale && denormalizedPagePath === '/'
Expand Down
11 changes: 3 additions & 8 deletions packages/next/next-server/lib/i18n/detect-locale-cookie.ts
@@ -1,15 +1,10 @@
import { IncomingMessage } from 'http'

export function detectLocaleCookie(req: IncomingMessage, locales: string[]) {
let detectedLocale: string | undefined

if (req.headers.cookie && req.headers.cookie.includes('NEXT_LOCALE')) {
const { NEXT_LOCALE } = (req as any).cookies

if (locales.some((locale: string) => NEXT_LOCALE === locale)) {
detectedLocale = NEXT_LOCALE
}
return locales.find(
(locale: string) => NEXT_LOCALE.toLowerCase() === locale.toLowerCase()
)
}

return detectedLocale
}
Expand Up @@ -10,7 +10,7 @@ export function normalizeLocalePath(
const pathnameParts = pathname.split('/')

;(locales || []).some((locale) => {
if (pathnameParts[1] === locale) {
if (pathnameParts[1].toLowerCase() === locale.toLowerCase()) {
detectedLocale = locale
pathnameParts.splice(1, 1)
pathname = pathnameParts.join('/') || '/'
Expand Down
6 changes: 4 additions & 2 deletions packages/next/next-server/server/next-server.ts
Expand Up @@ -324,9 +324,11 @@ export default class Server {

const denormalizedPagePath = denormalizePagePath(pathname || '/')
const detectedDefaultLocale =
!detectedLocale || detectedLocale === defaultLocale
!detectedLocale ||
detectedLocale.toLowerCase() === defaultLocale.toLowerCase()
const shouldStripDefaultLocale =
detectedDefaultLocale && denormalizedPagePath === `/${defaultLocale}`
detectedDefaultLocale &&
denormalizedPagePath.toLowerCase() === `/${defaultLocale.toLowerCase()}`
const shouldAddLocalePrefix =
!detectedDefaultLocale && denormalizedPagePath === '/'

Expand Down
28 changes: 26 additions & 2 deletions test/integration/i18n-support/test/index.test.js
Expand Up @@ -173,6 +173,15 @@ function runTests() {
expect($('#router-as-path').text()).toBe('/gsp')
expect($('#router-pathname').text()).toBe('/gsp')
expect(JSON.parse($('#router-locales').text())).toEqual(locales)

// make sure locale is case-insensitive
const html2 = await renderViaHTTP(appPort, `/${locale.toUpperCase()}/gsp`)
const $2 = cheerio.load(html2)
expect($2('html').attr('lang')).toBe(locale)
expect($2('#router-locale').text()).toBe(locale)
expect($2('#router-as-path').text()).toBe('/gsp')
expect($2('#router-pathname').text()).toBe('/gsp')
expect(JSON.parse($2('#router-locales').text())).toEqual(locales)
}
})

Expand All @@ -193,6 +202,21 @@ function runTests() {

expect(parsedUrl.pathname).toBe('/')
expect(parsedUrl.query).toEqual({})

// make sure locale is case-insensitive
const res2 = await fetchViaHTTP(appPort, '/eN-Us', undefined, {
redirect: 'manual',
headers: {
'Accept-Language': 'en-US;q=0.9',
},
})

expect(res2.status).toBe(307)

const parsedUrl2 = url.parse(res.headers.get('location'), true)

expect(parsedUrl2.pathname).toBe('/')
expect(parsedUrl2.query).toEqual({})
})

it('should load getStaticProps page correctly SSR (default locale no prefix)', async () => {
Expand Down Expand Up @@ -391,8 +415,8 @@ function runTests() {
it('should navigate client side for default locale with no prefix', async () => {
const browser = await webdriver(appPort, '/')
// make sure default locale is used in case browser isn't set to
// favor en-US by default
await browser.manage().addCookie({ name: 'NEXT_LOCALE', value: 'en-US' })
// favor en-US by default, (we use all caps to ensure it's case-insensitive)
await browser.manage().addCookie({ name: 'NEXT_LOCALE', value: 'EN-US' })
await browser.get(browser.initUrl)

const checkIndexValues = async () => {
Expand Down

0 comments on commit 1eeac4f

Please sign in to comment.