Support automatic language selection based on system language (#17953)

* Support automatic language selection

* Handle non-matching keys

* Cleanup

* Handle region specific language codes from browser

* Fix passing in requestor
This commit is contained in:
Nicolas Mowen
2025-04-29 09:02:50 -06:00
committed by GitHub
parent 9291543705
commit e57dde7bb0
4 changed files with 55 additions and 25 deletions

View File

@@ -1,15 +1,14 @@
import { createContext, useContext, useState, useEffect, useMemo } from "react";
import i18next from "i18next";
import { supportedLanguageKeys } from "@/lib/const";
type LanguageProviderState = {
language: string;
systemLanguage: string;
setLanguage: (language: string) => void;
};
const initialState: LanguageProviderState = {
language: i18next.language || "en",
systemLanguage: "en",
setLanguage: () => null,
};
@@ -26,10 +25,31 @@ export function LanguageProvider({
defaultLanguage?: string;
storageKey?: string;
}) {
const systemLanguage = useMemo<string>(() => {
if (typeof window === "undefined") return defaultLanguage;
const systemLanguage = window.navigator.language;
if (supportedLanguageKeys.includes(systemLanguage)) {
return systemLanguage;
}
// browser languages may include a -REGION (ex: en-US)
if (systemLanguage.includes("-")) {
const shortenedSystemLanguage = systemLanguage.split("-")[0];
if (supportedLanguageKeys.includes(shortenedSystemLanguage)) {
return shortenedSystemLanguage;
}
}
return defaultLanguage;
}, [defaultLanguage]);
const [language, setLanguage] = useState<string>(() => {
try {
const storedData = localStorage.getItem(storageKey);
const newLanguage = storedData || defaultLanguage;
const newLanguage = storedData || systemLanguage;
i18next.changeLanguage(newLanguage);
return newLanguage;
} catch (error) {
@@ -39,11 +59,6 @@ export function LanguageProvider({
}
});
const systemLanguage = useMemo<string>(() => {
if (typeof window === "undefined") return "en";
return window.navigator.language;
}, []);
useEffect(() => {
// set document lang for smart capitalization
document.documentElement.lang = language;
@@ -54,7 +69,6 @@ export function LanguageProvider({
const value = {
language,
systemLanguage,
setLanguage: (language: string) => {
localStorage.setItem(storageKey, language);
setLanguage(language);