website/assets/i18n.js
Didictateur 1fde29fe48 Recovered local commits:\n\nfd48e71 Didictateur <adrien.decosse@gmail.com> same header for alln
bb53e8 Didictateur <adrien.decosse@gmail.com> traduction en anglaisn
2025-11-22 12:56:33 +01:00

58 lines
1.8 KiB
JavaScript

// Simple client-side i18n loader using JSON files in /locales/
(function(){
const defaultLang = localStorage.getItem('lang') || (navigator.language && navigator.language.startsWith && navigator.language.startsWith('en') ? 'en' : 'fr');
let current = defaultLang;
async function loadLocale(lang){
try{
const res = await fetch(`locales/${lang}.json`);
if(!res.ok) throw new Error('locale not found');
return await res.json();
}catch(e){
console.error('i18n load error', e);
return {};
}
}
function applyTranslations(messages){
document.querySelectorAll('[data-i18n]').forEach(el => {
const key = el.getAttribute('data-i18n');
const txt = messages[key];
if(!txt) return;
if(el.placeholder !== undefined && el.tagName.toLowerCase()==='input'){
el.placeholder = txt;
} else if (el.hasAttribute('data-i18n-html')) {
el.innerHTML = txt;
} else {
el.textContent = txt;
}
});
}
async function setLang(lang){
const messages = await loadLocale(lang);
applyTranslations(messages);
localStorage.setItem('lang', lang);
current = lang;
try{ document.documentElement.lang = lang; }catch(e){}
document.querySelectorAll('.lang-toggle').forEach(btn => {
btn.classList.toggle('active', btn.getAttribute('data-lang')===lang);
});
}
// init on DOMContentLoaded
document.addEventListener('DOMContentLoaded', () => {
// attach toggles
document.querySelectorAll('.lang-toggle').forEach(btn => {
btn.addEventListener('click', e => {
e.preventDefault();
const l = btn.getAttribute('data-lang');
setLang(l);
});
});
setLang(current);
});
// expose for debug
window.__i18n = { setLang };
})();