fix: implement dynamic i18n translation loading with flattening

This commit is contained in:
gnezim
2026-04-06 10:10:23 +03:00
parent d0a0db5c75
commit 1b5f07249d
+54 -5
View File
@@ -1,7 +1,25 @@
import i18n from 'i18next'
import HttpBackend from 'i18next-http-backend'
import { initReactI18next } from 'react-i18next'
// Flatten nested translation objects
const flattenTranslations = (obj: any, prefix = ''): Record<string, string> => {
const result: Record<string, string> = {}
const flatten = (current: any, path: string) => {
if (typeof current === 'string') {
result[path] = current
} else if (typeof current === 'object' && current !== null && !Array.isArray(current)) {
for (const key in current) {
const newPath = path ? `${path}.${key}` : key
flatten(current[key], newPath)
}
}
}
flatten(obj, prefix)
return result
}
// Language detection logic
const getInitialLanguage = (): string => {
const stored = localStorage.getItem('i18nextLng')
@@ -31,17 +49,25 @@ const getInitialLanguage = (): string => {
const lng = getInitialLanguage()
// Initialize with empty resources, will be loaded dynamically
i18n
.use(HttpBackend)
.use(initReactI18next)
.init({
resources: {
ru: { translation: {} },
en: { translation: {} },
es: { translation: {} },
fr: { translation: {} },
it: { translation: {} },
ja: { translation: {} },
ko: { translation: {} },
de: { translation: {} },
zh: { translation: {} },
},
fallbackLng: 'ru',
lng,
defaultNS: 'translation',
ns: ['translation'],
backend: {
loadPath: '/assets/i18n/{{lng}}.json',
},
interpolation: {
escapeValue: false,
},
@@ -50,4 +76,27 @@ i18n
},
})
// Load translations dynamically
const loadLanguage = async (language: string) => {
try {
const response = await fetch(`/assets/i18n/${language}.json`)
if (!response.ok) throw new Error(`Failed to load ${language} translations`)
const data = await response.json()
const flattened = flattenTranslations(data)
i18n.addResourceBundle(language, 'translation', flattened, true, true)
} catch (error) {
console.error(`Error loading ${language} translations:`, error)
}
}
// Load current language
loadLanguage(lng).then(() => {
// Also preload fallback language
if (lng !== 'ru') {
loadLanguage('ru')
}
})
export default i18n