xref: /openbmc/webui-vue/src/i18n.js (revision 063a8e0efc946b319300c610a3fb44dde4433d31)
1import { createI18n } from 'vue-i18n';
2import { deepMerge } from './utilities/objectUtils';
3
4// Vite's import.meta.glob for dynamic imports
5const baseLocaleModules = import.meta.glob('./locales/**/*.json', {
6  eager: true,
7});
8const envLocaleModules = import.meta.glob('./env/locales/**/*.json', {
9  eager: true,
10});
11
12export function loadBaseLocaleMessages() {
13  const messages = {};
14  Object.entries(baseLocaleModules).forEach(([path, mod]) => {
15    const match = path.match(/([A-Za-z0-9-_]+)\.json$/i);
16    if (!match) return;
17    const locale = match[1];
18    messages[locale] = mod.default || mod;
19  });
20  return messages;
21}
22
23export function loadEnvLocaleMessages(envName) {
24  if (!envName) return {};
25  const envMessages = {};
26  const vendorRoot = String(envName).split('-')[0];
27  const candidates =
28    vendorRoot && vendorRoot !== envName ? [vendorRoot, envName] : [envName];
29
30  candidates.forEach((candidate) => {
31    Object.entries(envLocaleModules).forEach(([path, mod]) => {
32      if (!path.includes(`/${candidate}/`)) return;
33      const localeMatch = path.match(/([A-Za-z0-9-_]+)\.json$/i);
34      if (!localeMatch) return;
35      const locale = localeMatch[1];
36      const bundle = mod.default || mod;
37      envMessages[locale] = deepMerge(envMessages[locale] || {}, bundle);
38    });
39  });
40  return envMessages;
41}
42
43export function createI18nInstance(
44  envName,
45  locale,
46  loadEnv = loadEnvLocaleMessages,
47  loadBase = loadBaseLocaleMessages,
48) {
49  const base = loadBase();
50  const env = loadEnv(envName);
51  const messages = { ...base };
52  Object.keys(env).forEach((loc) => {
53    messages[loc] = deepMerge(base[loc] || {}, env[loc]);
54  });
55
56  const addAlias = (alias, target) => {
57    if (!messages[alias] && messages[target])
58      messages[alias] = messages[target];
59  };
60  addAlias('en', 'en-US');
61  addAlias('ru', 'ru-RU');
62  addAlias('zh', 'zh-CN');
63  addAlias('ka', 'ka-GE');
64
65  const normalize = (val) => {
66    if (!val) return undefined;
67    const s = String(val);
68    if (s === 'en') return 'en-US';
69    if (s === 'ru') return 'ru-RU';
70    if (s === 'zh') return 'zh-CN';
71    if (s === 'ka') return 'ka-GE';
72    return s;
73  };
74
75  return createI18n({
76    locale: normalize(locale),
77    // Locales that don't exist will fallback to English
78    fallbackLocale: 'en-US',
79    // Falling back to fallbackLocale generates two console warnings
80    // Silent fallback suppresses console warnings when using fallback
81    silentFallbackWarn: true,
82    messages,
83    globalInjection: true,
84    legacy: false,
85  });
86}
87
88const envName = import.meta.env.VITE_ENV_NAME;
89// Get default locale from local storage
90const stored = window.localStorage.getItem('storedLanguage');
91export default createI18nInstance(envName, stored);
92