From d8afc6b2be68ad9f2fe2e47367bde8b93421503d Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 4 Feb 2026 21:04:28 +0100 Subject: [PATCH] fix(i18n): respect browser preferred languages when supported (#6812) * fix(i18n): respect browser preferred languages when supported Instead of relying on the first browser language, the application now iterates through navigator.languages and selects the first supported locale, with a fallback to English. * chore: add the release notes related file * fix(i18n): check region locales support before falling back to base locale * fix(i18n): make the unit test aligned with the region locales checking --- packages/desktop-client/src/i18n.test.ts | 2 +- packages/desktop-client/src/i18n.ts | 73 ++++++++++++++---------- upcoming-release-notes/6812.md | 6 ++ 3 files changed, 49 insertions(+), 32 deletions(-) create mode 100644 upcoming-release-notes/6812.md diff --git a/packages/desktop-client/src/i18n.test.ts b/packages/desktop-client/src/i18n.test.ts index 5317629b0a..c433a8d3c6 100644 --- a/packages/desktop-client/src/i18n.test.ts +++ b/packages/desktop-client/src/i18n.test.ts @@ -71,7 +71,7 @@ describe('setI18NextLanguage', () => { setI18NextLanguage('uk-ZZ'); expect(console.info).toHaveBeenCalledWith( - 'Unknown locale uk-ZZ, falling back to uk', + 'Unknown locale uk-ZZ, falling back to uk-zz', ); expect(i18n.changeLanguage).toHaveBeenCalledWith('uk'); }); diff --git a/packages/desktop-client/src/i18n.ts b/packages/desktop-client/src/i18n.ts index fae40cd2d5..c9be051555 100644 --- a/packages/desktop-client/src/i18n.ts +++ b/packages/desktop-client/src/i18n.ts @@ -40,44 +40,55 @@ i18n }, }); +const resolveLanguage = (language: string) => { + // English is always available since we use natural-language keys. + if (language === 'en') return 'en'; + + if (isLanguageAvailable(language)) return language; + + const lowercaseLanguage = language.toLowerCase(); + if (lowercaseLanguage !== language) { + console.info( + `Unknown locale ${language}, falling back to ${lowercaseLanguage}`, + ); + return resolveLanguage(lowercaseLanguage); + } + + if (language.includes('-')) { + const fallback = language.split('-')[0]; + console.info(`Unknown locale ${language}, falling back to ${fallback}`); + return resolveLanguage(fallback); + } + + return undefined; +}; + export const setI18NextLanguage = (language: string) => { - if (!language) { - // System default - setI18NextLanguage(navigator.language || 'en'); - return; + const defaultLanguages = Array.isArray(navigator.languages) + ? navigator.languages + : [navigator.language || 'en']; + const languagesToTry = language ? [language] : defaultLanguages; + + let resolved: string | undefined; + + for (const lang of languagesToTry) { + resolved = resolveLanguage(lang); + if (resolved) break; } - if (!isLanguageAvailable(language)) { - if (language === 'en') { - // English is always available since we use natural-language keys. - return; - } - - if (language.includes('-')) { - const fallback = language.split('-')[0]; - console.info(`Unknown locale ${language}, falling back to ${fallback}`); - setI18NextLanguage(fallback); - return; - } - - const lowercaseLanguage = language.toLowerCase(); - if (lowercaseLanguage !== language) { - console.info( - `Unknown locale ${language}, falling back to ${lowercaseLanguage}`, - ); - setI18NextLanguage(lowercaseLanguage); - return; - } - + if (!resolved) { // Fall back to English - console.info(`Unknown locale ${language}, falling back to en`); - setI18NextLanguage('en'); - return; + console.info( + language + ? `Unknown locale ${language}, falling back to en` + : `Unknown locales [${languagesToTry.join(', ')}] falling back to en`, + ); + resolved = 'en'; } - if (language === i18n.language) { + if (resolved === i18n.language) { return; // language is already set } - i18n.changeLanguage(language || 'en'); + i18n.changeLanguage(resolved); }; diff --git a/upcoming-release-notes/6812.md b/upcoming-release-notes/6812.md new file mode 100644 index 0000000000..960836b764 --- /dev/null +++ b/upcoming-release-notes/6812.md @@ -0,0 +1,6 @@ +--- +category: Bugfixes +authors: [elevennprime] +--- + +The app now checks your preferred browser languages in order and uses the first one we support, otherwise English.