fix(i18n): resolve footer translation keys showing on non-homepage pages
SUMMARY: Fixed critical bug where footer displayed translation keys (e.g., "footer.about_heading") instead of actual text on all pages except homepage. ROOT CAUSE: i18n-simple.js only loaded page-specific JSON files (e.g., privacy.json). Footer translations were in homepage.json, so other pages couldn't access them. SOLUTION: 1. Created common.json for Shared Translations: - Created locales/en/common.json (footer translations) - Created locales/de/common.json (footer translations) - Created locales/fr/common.json (footer translations) 2. Updated i18n-simple.js to Load Both: - Always loads common.json (footer, shared UI elements) - Loads page-specific JSON (privacy.json, about.json, etc.) - Merges both (page-specific takes precedence) IMPACT: ✓ Footer now displays correctly in all 3 languages on ALL pages ✓ Privacy page: Footer translates properly (en/de/fr) ✓ All pages: Footer translations work regardless of page-specific JSON ✓ Scalable: Easy to add more shared translations to common.json TESTING: - Verified locally on privacy.html (footer displays "Tractatus Framework") - All 3 languages load correctly from common.json - Page-specific translations still work (privacy content translates) 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
31ed5b8a77
commit
780becc9ea
4 changed files with 113 additions and 4 deletions
|
|
@ -74,13 +74,29 @@ const I18n = {
|
|||
|
||||
async loadTranslations(lang) {
|
||||
try {
|
||||
// Always load common translations (footer, navbar, etc.)
|
||||
const commonResponse = await fetch(`/locales/${lang}/common.json`);
|
||||
let commonTranslations = {};
|
||||
if (commonResponse.ok) {
|
||||
commonTranslations = await commonResponse.json();
|
||||
}
|
||||
|
||||
// Load page-specific translations
|
||||
const pageName = this.detectPageName();
|
||||
const response = await fetch(`/locales/${lang}/${pageName}.json`);
|
||||
if (!response.ok) {
|
||||
const pageResponse = await fetch(`/locales/${lang}/${pageName}.json`);
|
||||
let pageTranslations = {};
|
||||
if (pageResponse.ok) {
|
||||
pageTranslations = await pageResponse.json();
|
||||
} else if (pageName !== 'homepage') {
|
||||
// If page-specific translations don't exist, that's okay for some pages
|
||||
console.warn(`[i18n] No translations found for ${lang}/${pageName}, using common only`);
|
||||
} else {
|
||||
throw new Error(`Failed to load translations for ${lang}/${pageName}`);
|
||||
}
|
||||
this.translations = await response.json();
|
||||
console.log(`[i18n] Loaded translations for page: ${pageName}`);
|
||||
|
||||
// Merge common and page-specific translations (page-specific takes precedence)
|
||||
this.translations = { ...commonTranslations, ...pageTranslations };
|
||||
console.log(`[i18n] Loaded translations: common + ${pageName}`);
|
||||
} catch (error) {
|
||||
console.error(`[i18n] Error loading translations:`, error);
|
||||
// Fallback to English if loading fails
|
||||
|
|
|
|||
31
public/locales/de/common.json
Normal file
31
public/locales/de/common.json
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"footer": {
|
||||
"about_heading": "Tractatus Framework",
|
||||
"about_text": "Architektonische Beschränkungen für KI-Sicherheit, die menschliche Entscheidungsfreiheit durch strukturelle, nicht aspirationale, Garantien wahren.",
|
||||
"documentation_heading": "Dokumentation",
|
||||
"documentation_links": {
|
||||
"framework_docs": "Framework-Dokumentation",
|
||||
"about": "Über uns",
|
||||
"core_values": "Grundwerte",
|
||||
"interactive_demo": "Interaktive Demo"
|
||||
},
|
||||
"support_heading": "Unterstützung",
|
||||
"support_links": {
|
||||
"koha": "Unterstützung (Koha)",
|
||||
"transparency": "Transparenz",
|
||||
"media_inquiries": "Medienanfragen",
|
||||
"submit_case": "Fallstudie einreichen"
|
||||
},
|
||||
"legal_heading": "Rechtliches",
|
||||
"legal_links": {
|
||||
"privacy": "Datenschutzerklärung",
|
||||
"contact": "Kontakt",
|
||||
"github": "GitHub"
|
||||
},
|
||||
"te_tiriti_label": "Te Tiriti o Waitangi:",
|
||||
"te_tiriti_text": "Wir erkennen Te Tiriti o Waitangi und unser Bekenntnis zu Partnerschaft, Schutz und Teilhabe an. Dieses Projekt respektiert die Māori-Datensouveränität (rangatiratanga) und kollektive Vormundschaft (kaitiakitanga).",
|
||||
"copyright": "John G Stroh. Lizenziert unter",
|
||||
"license": "Apache 2.0",
|
||||
"location": "Hergestellt in Aotearoa Neuseeland 🇳🇿"
|
||||
}
|
||||
}
|
||||
31
public/locales/en/common.json
Normal file
31
public/locales/en/common.json
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"footer": {
|
||||
"about_heading": "Tractatus Framework",
|
||||
"about_text": "Architectural constraints for AI safety that preserve human agency through structural, not aspirational, guarantees.",
|
||||
"documentation_heading": "Documentation",
|
||||
"documentation_links": {
|
||||
"framework_docs": "Framework Docs",
|
||||
"about": "About",
|
||||
"core_values": "Core Values",
|
||||
"interactive_demo": "Interactive Demo"
|
||||
},
|
||||
"support_heading": "Support",
|
||||
"support_links": {
|
||||
"koha": "Support (Koha)",
|
||||
"transparency": "Transparency",
|
||||
"media_inquiries": "Media Inquiries",
|
||||
"submit_case": "Submit Case Study"
|
||||
},
|
||||
"legal_heading": "Legal",
|
||||
"legal_links": {
|
||||
"privacy": "Privacy Policy",
|
||||
"contact": "Contact Us",
|
||||
"github": "GitHub"
|
||||
},
|
||||
"te_tiriti_label": "Te Tiriti o Waitangi:",
|
||||
"te_tiriti_text": "We acknowledge Te Tiriti o Waitangi and our commitment to partnership, protection, and participation. This project respects Māori data sovereignty (rangatiratanga) and collective guardianship (kaitiakitanga).",
|
||||
"copyright": "John G Stroh. Licensed under",
|
||||
"license": "Apache 2.0",
|
||||
"location": "Made in Aotearoa New Zealand 🇳🇿"
|
||||
}
|
||||
}
|
||||
31
public/locales/fr/common.json
Normal file
31
public/locales/fr/common.json
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"footer": {
|
||||
"about_heading": "Tractatus Framework",
|
||||
"about_text": "Contraintes architecturales pour la sécurité de l'IA qui préservent l'autonomie humaine par des garanties structurelles, et non aspirationnelles.",
|
||||
"documentation_heading": "Documentation",
|
||||
"documentation_links": {
|
||||
"framework_docs": "Documentation du Framework",
|
||||
"about": "À propos",
|
||||
"core_values": "Valeurs fondamentales",
|
||||
"interactive_demo": "Démo interactive"
|
||||
},
|
||||
"support_heading": "Support",
|
||||
"support_links": {
|
||||
"koha": "Support (Koha)",
|
||||
"transparency": "Transparence",
|
||||
"media_inquiries": "Demandes des médias",
|
||||
"submit_case": "Soumettre une étude de cas"
|
||||
},
|
||||
"legal_heading": "Légal",
|
||||
"legal_links": {
|
||||
"privacy": "Politique de confidentialité",
|
||||
"contact": "Nous contacter",
|
||||
"github": "GitHub"
|
||||
},
|
||||
"te_tiriti_label": "Te Tiriti o Waitangi :",
|
||||
"te_tiriti_text": "Nous reconnaissons Te Tiriti o Waitangi et notre engagement envers le partenariat, la protection et la participation. Ce projet respecte la souveraineté des données māori (rangatiratanga) et la tutelle collective (kaitiakitanga).",
|
||||
"copyright": "John G Stroh. Sous licence",
|
||||
"license": "Apache 2.0",
|
||||
"location": "Fabriqué en Aotearoa Nouvelle-Zélande 🇳🇿"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue