/** * i18n Configuration * * Configures i18next for internationalization support. * Features: * - Lazy-loading of translation namespaces * - Language detection from localStorage * - Fallback to English for missing translations * - Development mode warnings for missing keys */ import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; // eslint-disable-next-line import-x/order import LanguageDetector from 'i18next-browser-languagedetector'; // Import translation resources import enCommon from './locales/en/common.json'; import enSettings from './locales/en/settings.json'; import enAuth from './locales/en/auth.json'; import enSidebar from './locales/en/sidebar.json'; import enChat from './locales/en/chat.json'; import enCodeEditor from './locales/en/codeEditor.json'; // eslint-disable-next-line import-x/order import enTasks from './locales/en/tasks.json'; import koCommon from './locales/ko/common.json'; import koSettings from './locales/ko/settings.json'; import koAuth from './locales/ko/auth.json'; import koSidebar from './locales/ko/sidebar.json'; import koChat from './locales/ko/chat.json'; // eslint-disable-next-line import-x/order import koCodeEditor from './locales/ko/codeEditor.json'; import zhCommon from './locales/zh-CN/common.json'; import zhSettings from './locales/zh-CN/settings.json'; import zhAuth from './locales/zh-CN/auth.json'; import zhSidebar from './locales/zh-CN/sidebar.json'; import zhChat from './locales/zh-CN/chat.json'; // eslint-disable-next-line import-x/order import zhCodeEditor from './locales/zh-CN/codeEditor.json'; import jaCommon from './locales/ja/common.json'; import jaSettings from './locales/ja/settings.json'; import jaAuth from './locales/ja/auth.json'; import jaSidebar from './locales/ja/sidebar.json'; import jaChat from './locales/ja/chat.json'; import jaCodeEditor from './locales/ja/codeEditor.json'; // eslint-disable-next-line import-x/order import jaTasks from './locales/ja/tasks.json'; // Import supported languages configuration import { languages } from './languages.js'; // Get saved language preference from localStorage const getSavedLanguage = () => { try { const saved = localStorage.getItem('userLanguage'); // Validate that the saved language is supported if (saved && languages.some(lang => lang.value === saved)) { return saved; } return 'en'; } catch { return 'en'; } }; // Initialize i18next i18n .use(LanguageDetector) // Detect user language .use(initReactI18next) // Pass i18n instance to react-i18next .init({ // Resources containing all translations resources: { en: { common: enCommon, settings: enSettings, auth: enAuth, sidebar: enSidebar, chat: enChat, codeEditor: enCodeEditor, tasks: enTasks, }, ko: { common: koCommon, settings: koSettings, auth: koAuth, sidebar: koSidebar, chat: koChat, codeEditor: koCodeEditor, }, 'zh-CN': { common: zhCommon, settings: zhSettings, auth: zhAuth, sidebar: zhSidebar, chat: zhChat, codeEditor: zhCodeEditor, }, ja: { common: jaCommon, settings: jaSettings, auth: jaAuth, sidebar: jaSidebar, chat: jaChat, codeEditor: jaCodeEditor, tasks: jaTasks, }, }, // Default language lng: getSavedLanguage(), // Fallback language when a translation is missing fallbackLng: 'en', // Enable debug mode in development (logs missing keys to console) debug: import.meta.env.DEV, // Namespaces - load only what's needed ns: ['common', 'settings', 'auth', 'sidebar', 'chat', 'codeEditor', 'tasks'], defaultNS: 'common', // Key separator for nested keys (default: '.') keySeparator: '.', // Namespace separator (default: ':') nsSeparator: ':', // Save missing translations (disabled - requires manual review) saveMissing: false, // Interpolation settings interpolation: { escapeValue: false, // React already escapes values }, // React-specific settings react: { useSuspense: true, // Use Suspense for lazy-loading bindI18n: 'languageChanged', // Re-render on language change bindI18nStore: false, // Don't re-render on resource changes }, // Detection options detection: { // Order of language detection (local storage first) order: ['localStorage'], // Keys to look for in localStorage lookupLocalStorage: 'userLanguage', // Cache user language caches: ['localStorage'], }, }); // Save language preference when it changes i18n.on('languageChanged', (lng) => { try { localStorage.setItem('userLanguage', lng); } catch (error) { console.error('Failed to save language preference:', error); } }); export default i18n;