Files
Paperless-Contracts/frontend/src/i18n.ts
2025-10-11 01:17:31 +02:00

69 lines
1.8 KiB
TypeScript

import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import en from "./locales/en/common.json";
import de from "./locales/de/common.json";
const LANGUAGE_STORAGE_KEY = "contract-companion.language";
const SUPPORTED_LANGUAGES = ["en", "de"] as const;
type SupportedLanguage = (typeof SUPPORTED_LANGUAGES)[number];
function normalizeLanguage(value?: string | null): SupportedLanguage {
if (!value) return "en";
const lower = value.toLowerCase();
const match = SUPPORTED_LANGUAGES.find((lang) => lower.startsWith(lang));
return match ?? "en";
}
function detectInitialLanguage(): SupportedLanguage {
if (typeof window === "undefined") {
return "en";
}
try {
const stored = window.localStorage.getItem(LANGUAGE_STORAGE_KEY);
if (stored) {
return normalizeLanguage(stored);
}
} catch {
// Access to localStorage might be blocked (e.g., privacy mode); ignore and fall back to navigator.
}
return normalizeLanguage(window.navigator.language);
}
const initialLanguage = detectInitialLanguage();
i18n.use(initReactI18next).init({
resources: {
en: { translation: en },
de: { translation: de }
},
lng: initialLanguage,
fallbackLng: "en",
supportedLngs: ["en", "de"],
interpolation: {
escapeValue: false
}
});
if (typeof window !== "undefined") {
const applyLanguageSideEffects = (lang: string) => {
const normalized = normalizeLanguage(lang);
try {
window.localStorage.setItem(LANGUAGE_STORAGE_KEY, normalized);
} catch {
// Ignore storage write failures (private mode, etc.)
}
if (typeof document !== "undefined") {
document.documentElement.setAttribute("lang", normalized);
}
};
applyLanguageSideEffects(initialLanguage);
i18n.on("languageChanged", applyLanguageSideEffects);
}
export default i18n;