1
0
mirror of synced 2025-12-21 02:46:50 -05:00

language redirects without cache (#25872)

* redirect to your preferred language (#25664)

* redirect to your preferred language

* refactorings

* use js-cookies

* make sure no cache when language is involved in the redirect

* fix tests
This commit is contained in:
Peter Bengtsson
2022-03-07 11:25:22 -05:00
committed by GitHub
parent 4e628d6c26
commit 9d4b913bdc
7 changed files with 167 additions and 46 deletions

View File

@@ -1,14 +1,17 @@
import libLanguages from '../lib/languages.js'
import languages, { languageKeys } from '../lib/languages.js'
import parser from 'accept-language-parser'
const languageCodes = Object.keys(libLanguages)
const chineseRegions = ['CN', 'HK']
// This value is replicated in two places! See <LanguagePicker/> component.
// Note, the only reason this is exported is to benefit the tests.
export const PREFERRED_LOCALE_COOKIE_NAME = 'preferredlang'
function translationExists(language) {
if (language.code === 'zh') {
return chineseRegions.includes(language.region)
}
return languageCodes.includes(language.code)
return languageKeys.includes(language.code)
}
function getLanguageCode(language) {
@@ -17,33 +20,41 @@ function getLanguageCode(language) {
function getUserLanguage(browserLanguages) {
try {
let userLanguage = getLanguageCode(browserLanguages[0])
let numTopPreferences = 1
for (let lang = 0; lang < browserLanguages.length; lang++) {
// If language has multiple regions, Chrome adds the non-region language to list
if (lang > 0 && browserLanguages[lang].code !== browserLanguages[lang - 1].code)
numTopPreferences++
if (translationExists(browserLanguages[lang]) && numTopPreferences < 3) {
userLanguage = getLanguageCode(browserLanguages[lang])
break
return getLanguageCode(browserLanguages[lang])
}
}
return userLanguage
} catch {
return undefined
}
}
function getUserLanguageFromCookie(req) {
const value = req.cookies[PREFERRED_LOCALE_COOKIE_NAME]
// But if it's a WIP language, reject it.
if (value && languages[value] && !languages[value].wip) {
return value
}
}
// determine language code from a path. Default to en if no valid match
export function getLanguageCodeFromPath(path) {
const maybeLanguage = (path.split('/')[path.startsWith('/_next/data/') ? 4 : 1] || '').slice(0, 2)
return languageCodes.includes(maybeLanguage) ? maybeLanguage : 'en'
return languageKeys.includes(maybeLanguage) ? maybeLanguage : 'en'
}
export default function detectLanguage(req, res, next) {
req.language = getLanguageCodeFromPath(req.path)
// Detecting browser language by user preference
const browserLanguages = parser.parse(req.headers['accept-language'])
req.userLanguage = getUserLanguage(browserLanguages)
req.userLanguage = getUserLanguageFromCookie(req)
if (!req.userLanguage) {
const browserLanguages = parser.parse(req.headers['accept-language'])
req.userLanguage = getUserLanguage(browserLanguages)
}
return next()
}