i18n.ts 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import type { Locale } from 'vue-i18n';
  2. import type { ImportLocaleFn, SupportedLanguagesType } from './typing';
  3. import { unref } from 'vue';
  4. import { createI18n } from 'vue-i18n';
  5. const loadedLanguages = new Set<string>();
  6. const i18n = createI18n({
  7. globalInjection: true,
  8. legacy: false,
  9. locale: '',
  10. messages: {},
  11. });
  12. const modules = import.meta.glob('./langs/*.json');
  13. const localesMap = loadLocalesMap(modules);
  14. /**
  15. * Load locale modules
  16. * @param modules
  17. */
  18. function loadLocalesMap(modules: Record<string, () => Promise<unknown>>) {
  19. const localesMap: Record<Locale, ImportLocaleFn> = {};
  20. for (const [path, loadLocale] of Object.entries(modules)) {
  21. const key = path.match(/([\w-]*)\.(yaml|yml|json)/)?.[1];
  22. if (key) {
  23. localesMap[key] = loadLocale as ImportLocaleFn;
  24. }
  25. }
  26. return localesMap;
  27. }
  28. /**
  29. * Set i18n language
  30. * @param locale
  31. */
  32. function setI18nLanguage(locale: Locale) {
  33. i18n.global.locale.value = locale;
  34. document?.querySelector('html')?.setAttribute('lang', locale);
  35. }
  36. /**
  37. * Load locale messages
  38. * @param lang
  39. */
  40. async function loadI18nMessages(lang: SupportedLanguagesType) {
  41. if (unref(i18n.global.locale) === lang) {
  42. return setI18nLanguage(lang);
  43. }
  44. if (loadedLanguages.has(lang)) {
  45. return setI18nLanguage(lang);
  46. }
  47. const message = await localesMap[lang]();
  48. i18n.global.setLocaleMessage(lang, message.default);
  49. loadedLanguages.add(lang);
  50. return setI18nLanguage(lang);
  51. }
  52. export { i18n, loadI18nMessages, loadLocalesMap, setI18nLanguage };