Files
voicebox/app/src/i18n/index.ts
T
James PineandClaude Opus 4.7 302e28e313 fix(i18n): ensure language switch actually re-renders the tree
- `nonExplicitSupportedLngs: true` was normalizing `zh-CN` → `zh` in
  some code paths; since we have explicit `zh-CN` resources, swap it
  for `load: 'currentOnly'` which keeps the code as-is.
- `react: { useSuspense: false }` — react-i18next v17 defaults Suspense
  on, which can silently suspend components mid-switch and look like
  "nothing happens" to the user.
- Use `i18n.language` (the raw current code) instead of
  `resolvedLanguage` in the selector so the dropdown always mirrors
  what we just set.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-04-20 02:52:08 -07:00

35 lines
963 B
TypeScript

import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import { initReactI18next } from 'react-i18next';
import en from './locales/en/translation.json';
import zhCN from './locales/zh-CN/translation.json';
export const SUPPORTED_LANGUAGES = [
{ code: 'en', label: 'English' },
{ code: 'zh-CN', label: '简体中文' },
] as const;
export type LanguageCode = (typeof SUPPORTED_LANGUAGES)[number]['code'];
i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources: {
en: { translation: en },
'zh-CN': { translation: zhCN },
},
fallbackLng: 'en',
supportedLngs: SUPPORTED_LANGUAGES.map((l) => l.code),
load: 'currentOnly',
interpolation: { escapeValue: false },
react: { useSuspense: false },
detection: {
order: ['localStorage', 'navigator'],
lookupLocalStorage: 'voicebox:lang',
caches: ['localStorage'],
},
});
export default i18n;