IntlProvider.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import { createIntl, createIntlCache } from "react-intl";
  2. import langDe from "./lang/de.json";
  3. import langEn from "./lang/en.json";
  4. import langEs from "./lang/es.json";
  5. import langIt from "./lang/it.json";
  6. import langJa from "./lang/ja.json";
  7. import langList from "./lang/lang-list.json";
  8. import langNl from "./lang/nl.json";
  9. import langPl from "./lang/pl.json";
  10. import langRu from "./lang/ru.json";
  11. import langSk from "./lang/sk.json";
  12. import langVi from "./lang/vi.json";
  13. import langZh from "./lang/zh.json";
  14. import langBg from "./lang/bg.json";
  15. // first item of each array should be the language code,
  16. // not the country code
  17. // Remember when adding to this list, also update check-locales.js script
  18. const localeOptions = [
  19. ["en", "en-US", langEn],
  20. ["de", "de-DE", langDe],
  21. ["es", "es-ES", langEs],
  22. ["ja", "ja-JP", langJa],
  23. ["it", "it-IT", langIt],
  24. ["nl", "nl-NL", langNl],
  25. ["pl", "pl-PL", langPl],
  26. ["ru", "ru-RU", langRu],
  27. ["sk", "sk-SK", langSk],
  28. ["vi", "vi-VN", langVi],
  29. ["zh", "zh-CN", langZh],
  30. ["bg", "bg-BG", langBg],
  31. ];
  32. const loadMessages = (locale?: string): typeof langList & typeof langEn => {
  33. const thisLocale = (locale || "en").slice(0, 2);
  34. // ensure this lang exists in localeOptions above, otherwise fallback to en
  35. if (thisLocale === "en" || !localeOptions.some(([code]) => code === thisLocale)) {
  36. return Object.assign({}, langList, langEn);
  37. }
  38. return Object.assign({}, langList, langEn, localeOptions.find(([code]) => code === thisLocale)?.[2]);
  39. };
  40. const getFlagCodeForLocale = (locale?: string) => {
  41. const thisLocale = (locale || "en").slice(0, 2);
  42. // only add to this if your flag is different from the locale code
  43. const specialCases: Record<string, string> = {
  44. ja: "jp", // Japan
  45. zh: "cn", // China
  46. vi: "vn", // Vietnam
  47. };
  48. if (specialCases[thisLocale]) {
  49. return specialCases[thisLocale].toUpperCase();
  50. }
  51. return thisLocale.toUpperCase();
  52. };
  53. const getLocale = (short = false) => {
  54. let loc = window.localStorage.getItem("locale");
  55. if (!loc) {
  56. loc = document.documentElement.lang;
  57. }
  58. if (short) {
  59. return loc.slice(0, 2);
  60. }
  61. // finally, fallback
  62. if (!loc) {
  63. loc = "en";
  64. }
  65. return loc;
  66. };
  67. const cache = createIntlCache();
  68. const initialMessages = loadMessages(getLocale());
  69. let intl = createIntl({ locale: getLocale(), messages: initialMessages }, cache);
  70. const changeLocale = (locale: string): void => {
  71. const messages = loadMessages(locale);
  72. intl = createIntl({ locale, messages }, cache);
  73. window.localStorage.setItem("locale", locale);
  74. document.documentElement.lang = locale;
  75. };
  76. // This is a translation component that wraps the translation in a span with a data
  77. // attribute so devs can inspect the element to see the translation ID
  78. const T = ({
  79. id,
  80. data,
  81. tData,
  82. }: {
  83. id: string;
  84. data?: Record<string, string | number | undefined>;
  85. tData?: Record<string, string>;
  86. }) => {
  87. const translatedData: Record<string, string> = {};
  88. if (tData) {
  89. // iterate over tData and translate each value
  90. Object.entries(tData).forEach(([key, value]) => {
  91. translatedData[key] = intl.formatMessage({ id: value });
  92. });
  93. }
  94. return (
  95. <span data-translation-id={id}>
  96. {intl.formatMessage(
  97. { id },
  98. {
  99. ...data,
  100. ...translatedData,
  101. },
  102. )}
  103. </span>
  104. );
  105. };
  106. console.log("L:", localeOptions);
  107. export { localeOptions, getFlagCodeForLocale, getLocale, createIntl, changeLocale, intl, T };