import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; // Note: LanguageDetector not used - we have custom detector // Only import German translations by default import translationDE from './locales/de/index.js'; import legalAgbDeliveryDE from './locales/de/legal-agb-delivery.js'; import legalAgbPaymentDE from './locales/de/legal-agb-payment.js'; import legalAgbConsumerDE from './locales/de/legal-agb-consumer.js'; import legalDatenschutzBasicDE from './locales/de/legal-datenschutz-basic.js'; import legalDatenschutzCustomerDE from './locales/de/legal-datenschutz-customer.js'; import legalDatenschutzGoogleOrdersDE from './locales/de/legal-datenschutz-google-orders.js'; import legalDatenschutzNewsletterDE from './locales/de/legal-datenschutz-newsletter.js'; import legalDatenschutzChatbotDE from './locales/de/legal-datenschutz-chatbot.js'; import legalDatenschutzCookiesPaymentDE from './locales/de/legal-datenschutz-cookies-payment.js'; import legalDatenschutzRightsDE from './locales/de/legal-datenschutz-rights.js'; import legalImpressumDE from './locales/de/legal-impressum.js'; import legalWiderrufDE from './locales/de/legal-widerruf.js'; import legalBatterieDE from './locales/de/legal-batterie.js'; // Language loading cache to prevent duplicate loads const languageCache = new Set(['de']); const loadingPromises = new Map(); // Lazy loading function for languages const loadLanguage = async (language) => { if (languageCache.has(language)) { return; // Already loaded } if (loadingPromises.has(language)) { return loadingPromises.get(language); // Already loading } const loadingPromise = (async () => { try { console.log(`🌍 Lazy loading language: ${language}`); // Dynamic imports for lazy loading const [ translation, legalAgbDelivery, legalAgbPayment, legalAgbConsumer, legalDatenschutzBasic, legalDatenschutzCustomer, legalDatenschutzGoogleOrders, legalDatenschutzNewsletter, legalDatenschutzChatbot, legalDatenschutzCookiesPayment, legalDatenschutzRights, legalImpressum, legalWiderruf, legalBatterie ] = await Promise.all([ import(`./locales/${language}/index.js`), import(`./locales/${language}/legal-agb-delivery.js`), import(`./locales/${language}/legal-agb-payment.js`), import(`./locales/${language}/legal-agb-consumer.js`), import(`./locales/${language}/legal-datenschutz-basic.js`), import(`./locales/${language}/legal-datenschutz-customer.js`), import(`./locales/${language}/legal-datenschutz-google-orders.js`), import(`./locales/${language}/legal-datenschutz-newsletter.js`), import(`./locales/${language}/legal-datenschutz-chatbot.js`), import(`./locales/${language}/legal-datenschutz-cookies-payment.js`), import(`./locales/${language}/legal-datenschutz-rights.js`), import(`./locales/${language}/legal-impressum.js`), import(`./locales/${language}/legal-widerruf.js`), import(`./locales/${language}/legal-batterie.js`) ]); // Add the loaded resources to i18n i18n.addResourceBundle(language, 'translation', translation.default); i18n.addResourceBundle(language, 'legal-agb-delivery', legalAgbDelivery.default); i18n.addResourceBundle(language, 'legal-agb-payment', legalAgbPayment.default); i18n.addResourceBundle(language, 'legal-agb-consumer', legalAgbConsumer.default); i18n.addResourceBundle(language, 'legal-datenschutz-basic', legalDatenschutzBasic.default); i18n.addResourceBundle(language, 'legal-datenschutz-customer', legalDatenschutzCustomer.default); i18n.addResourceBundle(language, 'legal-datenschutz-google-orders', legalDatenschutzGoogleOrders.default); i18n.addResourceBundle(language, 'legal-datenschutz-newsletter', legalDatenschutzNewsletter.default); i18n.addResourceBundle(language, 'legal-datenschutz-chatbot', legalDatenschutzChatbot.default); i18n.addResourceBundle(language, 'legal-datenschutz-cookies-payment', legalDatenschutzCookiesPayment.default); i18n.addResourceBundle(language, 'legal-datenschutz-rights', legalDatenschutzRights.default); i18n.addResourceBundle(language, 'legal-impressum', legalImpressum.default); i18n.addResourceBundle(language, 'legal-widerruf', legalWiderruf.default); i18n.addResourceBundle(language, 'legal-batterie', legalBatterie.default); languageCache.add(language); console.log(`✅ Language ${language} loaded successfully`); } catch (error) { console.error(`❌ Failed to load language ${language}:`, error); throw error; } finally { loadingPromises.delete(language); } })(); loadingPromises.set(language, loadingPromise); return loadingPromise; }; // Custom language detector that prioritizes session storage and defaults to German const customDetector = { name: 'customDetector', lookup() { // Only try storage in browser environment if (typeof window === 'undefined') { return 'de'; } // 1. Check session storage first try { if (typeof sessionStorage !== 'undefined') { const sessionLang = sessionStorage.getItem('i18nextLng'); if (sessionLang && sessionLang !== 'de') { return sessionLang; } } } catch { // Session storage not available } // 2. Check localStorage try { if (typeof localStorage !== 'undefined') { const localLang = localStorage.getItem('i18nextLng'); if (localLang && localLang !== 'de') { return localLang; } } } catch { // LocalStorage not available } // 3. Always default to German (don't detect browser language) return 'de'; }, cacheUserLanguage(lng) { // Only cache in browser environment if (typeof window === 'undefined') { return; } try { if (typeof sessionStorage !== 'undefined') { sessionStorage.setItem('i18nextLng', lng); } if (typeof localStorage !== 'undefined') { localStorage.setItem('i18nextLng', lng); } } catch { // Storage not available } } }; // Initialize i18n with only German resources const resources = { de: { translation: translationDE, 'legal-agb-delivery': legalAgbDeliveryDE, 'legal-agb-payment': legalAgbPaymentDE, 'legal-agb-consumer': legalAgbConsumerDE, 'legal-datenschutz-basic': legalDatenschutzBasicDE, 'legal-datenschutz-customer': legalDatenschutzCustomerDE, 'legal-datenschutz-google-orders': legalDatenschutzGoogleOrdersDE, 'legal-datenschutz-newsletter': legalDatenschutzNewsletterDE, 'legal-datenschutz-chatbot': legalDatenschutzChatbotDE, 'legal-datenschutz-cookies-payment': legalDatenschutzCookiesPaymentDE, 'legal-datenschutz-rights': legalDatenschutzRightsDE, 'legal-impressum': legalImpressumDE, 'legal-widerruf': legalWiderrufDE, 'legal-batterie': legalBatterieDE } }; i18n .use({ type: 'languageDetector', async: false, detect: customDetector.lookup, init() {}, cacheUserLanguage: customDetector.cacheUserLanguage }) .use(initReactI18next) .init({ resources, fallbackLng: 'de', debug: process.env.NODE_ENV === 'development', // Disable automatic language detection from browser detection: { order: ['customDetector'], caches: ['localStorage', 'sessionStorage'] }, interpolation: { escapeValue: false // React already escapes values }, // Namespace configuration defaultNS: 'translation', // React-specific options react: { useSuspense: false // Disable suspense for class components compatibility }, // Load missing keys as fallback saveMissing: process.env.NODE_ENV === 'development' }); // Override changeLanguage to load languages on demand const originalChangeLanguage = i18n.changeLanguage.bind(i18n); i18n.changeLanguage = async (language) => { if (language !== 'de' && !languageCache.has(language)) { try { await loadLanguage(language); } catch { console.error(`Failed to load language ${language}, falling back to German`); language = 'de'; } } return originalChangeLanguage(language); }; // Check session storage on initialization and load language if needed const initializeLanguage = async () => { // Only run in browser environment if (typeof window === 'undefined' || typeof sessionStorage === 'undefined') { return; } try { const sessionLang = sessionStorage.getItem('i18nextLng'); if (sessionLang && sessionLang !== 'de' && !languageCache.has(sessionLang)) { console.log(`🔄 Restoring session language: ${sessionLang}`); await loadLanguage(sessionLang); await i18n.changeLanguage(sessionLang); } } catch { console.warn('Failed to restore session language'); } }; // Initialize language on DOM ready (browser only) if (typeof window !== 'undefined' && typeof document !== 'undefined') { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initializeLanguage); } else { initializeLanguage(); } } export default i18n; export { loadLanguage }; // Re-export withI18n and other utilities for compatibility export { withI18n, withTranslation, withLanguage, LanguageContext, LanguageProvider } from './withTranslation.js';