fix(lang): respect fallback languages

If `navigator.languages` returns `['da', 'en-US', 'en']`, and the Danish
language is not available, the user interface should be in English.

Currently it is shown in Norwegian, because only `'da'` is taken into
account when deciding on the preferred language (and `match` selects
`nb-NO` using the default `'best fit'` algorithm).

While the Norwegian and Danish languages are similar, I would argue that
this is a bug, as `navigator.languages` cleary states that the fallback
language should be English.

Another potential solution would be to pass `{ algorithm: 'lookup' }` to
the `match` function. However, this might break some cases when a
`'best fit'` approach would be appropriate (e.g. Swiss German falling
back to German).

See https://helvede.net/@jwcph/113497955274343365.
This commit is contained in:
Sorin Davidoi 2024-11-19 00:31:29 +02:00
parent 06b56a8c67
commit 46b5faab31
No known key found for this signature in database

View file

@ -1,9 +1,9 @@
import { i18n } from '@lingui/core'; import { i18n } from '@lingui/core';
import { import {
detect,
fromNavigator, fromNavigator,
fromStorage, fromStorage,
fromUrl, fromUrl,
multipleDetect,
} from '@lingui/detect-locale'; } from '@lingui/detect-locale';
import Locale from 'intl-locale-textinfo-polyfill'; import Locale from 'intl-locale-textinfo-polyfill';
@ -54,7 +54,7 @@ export async function activateLang(lang) {
} }
export function initActivateLang() { export function initActivateLang() {
const lang = detect( const languages = multipleDetect(
fromUrl('lang'), fromUrl('lang'),
fromStorage('lang'), fromStorage('lang'),
fromNavigator(), fromNavigator(),
@ -62,7 +62,8 @@ export function initActivateLang() {
DEFAULT_LANG, DEFAULT_LANG,
); );
const matchedLang = const matchedLang =
ALL_LOCALES.find((l) => l === lang) || localeMatch(lang, ALL_LOCALES); languages.find((l) => ALL_LOCALES.includes(l)) ||
localeMatch(languages, ALL_LOCALES);
activateLang(matchedLang); activateLang(matchedLang);
// const yes = confirm(t`Reload to apply language setting?`); // const yes = confirm(t`Reload to apply language setting?`);