47 lines
No EOL
1.3 KiB
JavaScript
47 lines
No EOL
1.3 KiB
JavaScript
import { derived, writable } from "svelte/store";
|
|
import translations from "./translations";
|
|
|
|
const storedLocale = localStorage.getItem("locale");
|
|
const browserLocale = navigator.language || "en";
|
|
const [baseLang] = browserLocale.split("-");
|
|
|
|
export const DEFAULT_LOCALE =
|
|
storedLocale && translations[storedLocale] ? storedLocale :
|
|
translations[browserLocale] ? browserLocale :
|
|
translations[baseLang] ? baseLang :
|
|
"en";
|
|
|
|
export const locale = writable(DEFAULT_LOCALE);
|
|
|
|
locale.subscribe((value) => {
|
|
if (value) localStorage.setItem("locale", value);
|
|
});
|
|
|
|
export const locales = Object.entries(translations).map(([key, lang]) => [key, lang.name]);
|
|
|
|
function translate(locale, key, vars = {}) {
|
|
if (!key) throw new Error("Translation key is required.");
|
|
|
|
const fallbackLocale = "en";
|
|
const validLocale = translations[locale]
|
|
? locale
|
|
: translations[baseLang]
|
|
? baseLang
|
|
: fallbackLocale;
|
|
|
|
let text = translations[validLocale][key] || translations[fallbackLocale][key];
|
|
|
|
if (!text) {
|
|
console.error(`Missing translation for key "${key}" in locale "${validLocale}".`);
|
|
return key;
|
|
}
|
|
|
|
return Object.entries(vars).reduce(
|
|
(str, [varKey, value]) => str.replaceAll(`{{${varKey}}}`, value),
|
|
text
|
|
);
|
|
}
|
|
|
|
export const t = derived(locale, ($locale) => (key, vars = {}) =>
|
|
translate($locale, key, vars)
|
|
); |