diff --git a/web/package.json b/web/package.json index efe29367..76d4f9ee 100644 --- a/web/package.json +++ b/web/package.json @@ -16,6 +16,7 @@ "dayjs": "^1.11.3", "highlight.js": "^11.6.0", "i18next": "^21.9.2", + "i18next-browser-languagedetector": "^7.0.1", "lodash-es": "^4.17.21", "lucide-react": "^0.105.0", "qrcode.react": "^3.1.0", diff --git a/web/src/i18n.ts b/web/src/i18n.ts index 3487d5c6..700bd2aa 100644 --- a/web/src/i18n.ts +++ b/web/src/i18n.ts @@ -1,5 +1,6 @@ import i18n from "i18next"; import { initReactI18next } from "react-i18next"; +import LanguageDetector from "i18next-browser-languagedetector"; import enLocale from "./locales/en.json"; import zhLocale from "./locales/zh.json"; import viLocale from "./locales/vi.json"; @@ -15,53 +16,60 @@ import hantLocale from "./locales/zh-Hant.json"; import trLocale from "./locales/tr.json"; import koLocale from "./locales/ko.json"; -i18n.use(initReactI18next).init({ - resources: { - en: { - translation: enLocale, +const DETECTION_OPTIONS = { + order: ["navigator"], +}; + +i18n + .use(LanguageDetector) + .use(initReactI18next) + .init({ + detection: DETECTION_OPTIONS, + resources: { + en: { + translation: enLocale, + }, + zh: { + translation: zhLocale, + }, + vi: { + translation: viLocale, + }, + fr: { + translation: frLocale, + }, + nl: { + translation: nlLocale, + }, + sv: { + translation: svLocale, + }, + de: { + translation: deLocale, + }, + es: { + translation: esLocale, + }, + uk: { + translation: ukLocale, + }, + ru: { + translation: ruLocale, + }, + it: { + translation: itLocale, + }, + hant: { + translation: hantLocale, + }, + tr: { + translation: trLocale, + }, + ko: { + translation: koLocale, + }, }, - zh: { - translation: zhLocale, - }, - vi: { - translation: viLocale, - }, - fr: { - translation: frLocale, - }, - nl: { - translation: nlLocale, - }, - sv: { - translation: svLocale, - }, - de: { - translation: deLocale, - }, - es: { - translation: esLocale, - }, - uk: { - translation: ukLocale, - }, - ru: { - translation: ruLocale, - }, - it: { - translation: itLocale, - }, - hant: { - translation: hantLocale, - }, - tr: { - translation: trLocale, - }, - ko: { - translation: koLocale, - }, - }, - lng: "en", - fallbackLng: "en", -}); + fallbackLng: "en", + }); export default i18n; diff --git a/web/src/store/module/global.ts b/web/src/store/module/global.ts index d994fa52..b83fe0a1 100644 --- a/web/src/store/module/global.ts +++ b/web/src/store/module/global.ts @@ -2,6 +2,8 @@ import * as api from "../../helpers/api"; import * as storage from "../../helpers/storage"; import store, { useAppSelector } from "../"; import { setAppearance, setGlobalState, setLocale } from "../reducer/global"; +import i18n from "../../i18n"; +import { convertLanguageCodeToLocale } from "../../utils/convertLanguageCodeToLocale"; export const initialGlobalState = async () => { const defaultGlobalState = { @@ -46,7 +48,7 @@ export const initialGlobalState = async () => { externalUrl: "", }, }; - defaultGlobalState.locale = customizedProfile.locale; + defaultGlobalState.locale = storageLocale || convertLanguageCodeToLocale(i18n.language); defaultGlobalState.appearance = customizedProfile.appearance; } } catch (error) { diff --git a/web/src/utils/convertLanguageCodeToLocale.ts b/web/src/utils/convertLanguageCodeToLocale.ts new file mode 100644 index 00000000..845b78b0 --- /dev/null +++ b/web/src/utils/convertLanguageCodeToLocale.ts @@ -0,0 +1,7 @@ +export const convertLanguageCodeToLocale = (codename: string): Locale => { + if (codename === "zh-TW" || codename === "zh-HK") { + return "hant"; + } + const shortCode = codename.substring(0, 2); + return shortCode as Locale; +};