From c16cea80c868d4af6bf12d793c595e9ade06b885 Mon Sep 17 00:00:00 2001 From: TheFlow Date: Sun, 19 Oct 2025 15:01:14 +1300 Subject: [PATCH] feat(i18n): enhance browser language detection with clear priority logging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SUMMARY: Enhanced i18n language detection to clearly show priority order and provide better logging for debugging user language preferences. PRIORITY ORDER: 1. User's manual selection (localStorage) - HIGHEST - Clicking language flags saves preference here - Allows users to override browser language 2. Browser's language setting (navigator.language) - AUTOMATIC - Detects from browser preferences - Only applies if no user override exists 3. Default to English (fallback) - Used when browser language not supported CHANGES: 1. Enhanced detectLanguage(): - Added clear comments documenting priority order - Added console.log for each detection path - Shows which source determined the language - Logs browser language even when not supported 2. Enhanced setLanguage(): - Added log when user manually selects language - Clarifies that preference overrides browser detection - Shows that preference persists across pages BENEFITS: ✓ Users see automatic language detection from browser ✓ Users can override via flag clicks (persists via localStorage) ✓ Clear logging helps debug language selection issues ✓ Developers can see exactly how language was determined EXAMPLE LOGS: - Browser detection: '[i18n] Language detected from browser: de (from de-DE)' - User override: '[i18n] User manually selected language: fr (saved to localStorage)' - Fallback: '[i18n] Language defaulted to: en (browser language 'ja-JP' not supported)' 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude --- .claude/metrics/hooks-metrics.json | 18 +++++++++++++-- public/js/i18n-simple.js | 35 +++++++++++++++++++----------- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/.claude/metrics/hooks-metrics.json b/.claude/metrics/hooks-metrics.json index 02b79c3e..7e22319e 100644 --- a/.claude/metrics/hooks-metrics.json +++ b/.claude/metrics/hooks-metrics.json @@ -3996,6 +3996,20 @@ "file": "/home/theflow/projects/tractatus/SCHEDULED_TASKS.md", "result": "passed", "reason": null + }, + { + "hook": "validate-file-edit", + "timestamp": "2025-10-19T02:00:49.054Z", + "file": "/home/theflow/projects/tractatus/public/js/i18n-simple.js", + "result": "passed", + "reason": null + }, + { + "hook": "validate-file-edit", + "timestamp": "2025-10-19T02:00:49.318Z", + "file": "/home/theflow/projects/tractatus/public/js/i18n-simple.js", + "result": "passed", + "reason": null } ], "blocks": [ @@ -4217,9 +4231,9 @@ } ], "session_stats": { - "total_edit_hooks": 391, + "total_edit_hooks": 393, "total_edit_blocks": 32, - "last_updated": "2025-10-19T01:58:00.384Z", + "last_updated": "2025-10-19T02:00:49.318Z", "total_write_hooks": 180, "total_write_blocks": 4 } diff --git a/public/js/i18n-simple.js b/public/js/i18n-simple.js index 18d0c7e4..b725a8be 100644 --- a/public/js/i18n-simple.js +++ b/public/js/i18n-simple.js @@ -25,19 +25,27 @@ const I18n = { }, detectLanguage() { - // Check localStorage first + // Priority order: + // 1. User's manual selection (localStorage) - allows override via flag clicks + // 2. Browser's language setting (automatic detection) + // 3. Default to English (fallback) + + // 1. Check localStorage first (user override) const saved = localStorage.getItem('tractatus-lang'); if (saved && this.supportedLanguages.includes(saved)) { + console.log(`[i18n] Language detected from user preference: ${saved}`); return saved; } - - // Check browser language + + // 2. Check browser language (automatic detection) const browserLang = (navigator.language || navigator.userLanguage).split('-')[0]; if (this.supportedLanguages.includes(browserLang)) { + console.log(`[i18n] Language detected from browser: ${browserLang} (from ${navigator.language})`); return browserLang; } - - // Default to English + + // 3. Default to English + console.log(`[i18n] Language defaulted to: en (browser language '${navigator.language}' not supported)`); return 'en'; }, @@ -160,22 +168,23 @@ const I18n = { console.error(`[i18n] Unsupported language: ${lang}`); return; } - - // Save preference + + // Save preference (overrides browser language detection) localStorage.setItem('tractatus-lang', lang); - + console.log(`[i18n] User manually selected language: ${lang} (saved to localStorage)`); + // Update current language this.currentLang = lang; - + // Reload translations await this.loadTranslations(lang); - + // Reapply to page this.applyTranslations(); - + // Update selector this.updateLanguageSelector(); - + // Update HTML lang attribute document.documentElement.lang = lang; @@ -184,7 +193,7 @@ const I18n = { detail: { language: lang } })); - console.log(`[i18n] Language changed to: ${lang}`); + console.log(`[i18n] Language changed to: ${lang} (will persist across pages)`); }, updateLanguageSelector() {