From 239b357e575de29131c6e3decc1bd10859c13dff Mon Sep 17 00:00:00 2001 From: Dan Lee Date: Fri, 20 Mar 2026 11:04:19 +0800 Subject: [PATCH] feat: auto-detect browser locale (zh-TW / zh / en) Falls back to navigator.languages when no saved preference exists in localStorage. Manual language selection still takes priority. Co-Authored-By: Claude Sonnet 4.6 --- lib/i18n.tsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/i18n.tsx b/lib/i18n.tsx index 02dd9cf..7d95338 100644 --- a/lib/i18n.tsx +++ b/lib/i18n.tsx @@ -883,6 +883,17 @@ const I18nContext = createContext({ t: (key) => key, }); +function detectBrowserLocale(): Locale { + const langs = navigator.languages?.length ? navigator.languages : [navigator.language]; + for (const lang of langs) { + const l = lang.toLowerCase(); + if (l.startsWith('zh-tw') || l.startsWith('zh-hant') || l.startsWith('zh-hk') || l.startsWith('zh-mo')) return 'zh-TW'; + if (l.startsWith('zh')) return 'zh'; + if (l.startsWith('en')) return 'en'; + } + return 'zh'; +} + export function I18nProvider({ children }: { children: ReactNode }) { const [locale, setLocaleState] = useState("zh"); @@ -890,6 +901,8 @@ export function I18nProvider({ children }: { children: ReactNode }) { const saved = localStorage.getItem("locale") as Locale; if (saved && (saved === "zh-TW" || saved === "zh" || saved === "en")) { setLocaleState(saved); + } else { + setLocaleState(detectBrowserLocale()); } }, []);