import { createIntl, createIntlCache } from "react-intl"; import langDe from "./lang/de.json"; import langEn from "./lang/en.json"; import langEs from "./lang/es.json"; import langIt from "./lang/it.json"; import langJa from "./lang/ja.json"; import langList from "./lang/lang-list.json"; import langNl from "./lang/nl.json"; import langPl from "./lang/pl.json"; import langRu from "./lang/ru.json"; import langSk from "./lang/sk.json"; import langVi from "./lang/vi.json"; import langZh from "./lang/zh.json"; import langKo from "./lang/ko.json"; import langBg from "./lang/bg.json"; // first item of each array should be the language code, // not the country code // Remember when adding to this list, also update check-locales.js script const localeOptions = [ ["en", "en-US", langEn], ["de", "de-DE", langDe], ["es", "es-ES", langEs], ["ja", "ja-JP", langJa], ["it", "it-IT", langIt], ["nl", "nl-NL", langNl], ["pl", "pl-PL", langPl], ["ru", "ru-RU", langRu], ["sk", "sk-SK", langSk], ["vi", "vi-VN", langVi], ["zh", "zh-CN", langZh], ["ko", "ko-KR", langKo], ["bg", "bg-BG", langBg], ]; const loadMessages = (locale?: string): typeof langList & typeof langEn => { const thisLocale = (locale || "en").slice(0, 2); // ensure this lang exists in localeOptions above, otherwise fallback to en if (thisLocale === "en" || !localeOptions.some(([code]) => code === thisLocale)) { return Object.assign({}, langList, langEn); } return Object.assign({}, langList, langEn, localeOptions.find(([code]) => code === thisLocale)?.[2]); }; const getFlagCodeForLocale = (locale?: string) => { const thisLocale = (locale || "en").slice(0, 2); // only add to this if your flag is different from the locale code const specialCases: Record = { ja: "jp", // Japan zh: "cn", // China vi: "vn", // Vietnam ko: "kr", // Korea }; if (specialCases[thisLocale]) { return specialCases[thisLocale].toUpperCase(); } return thisLocale.toUpperCase(); }; const getLocale = (short = false) => { let loc = window.localStorage.getItem("locale"); if (!loc) { loc = document.documentElement.lang; } if (short) { return loc.slice(0, 2); } // finally, fallback if (!loc) { loc = "en"; } return loc; }; const cache = createIntlCache(); const initialMessages = loadMessages(getLocale()); let intl = createIntl({ locale: getLocale(), messages: initialMessages }, cache); const changeLocale = (locale: string): void => { const messages = loadMessages(locale); intl = createIntl({ locale, messages }, cache); window.localStorage.setItem("locale", locale); document.documentElement.lang = locale; }; // This is a translation component that wraps the translation in a span with a data // attribute so devs can inspect the element to see the translation ID const T = ({ id, data, tData, }: { id: string; data?: Record; tData?: Record; }) => { const translatedData: Record = {}; if (tData) { // iterate over tData and translate each value Object.entries(tData).forEach(([key, value]) => { translatedData[key] = intl.formatMessage({ id: value }); }); } return ( {intl.formatMessage( { id }, { ...data, ...translatedData, }, )} ); }; console.log("L:", localeOptions); export { localeOptions, getFlagCodeForLocale, getLocale, createIntl, changeLocale, intl, T };