Files
infiplot-web/docs/i18n-implementation.md
T
DESKTOP-I1T6TF3\Q 2d35c1d9de feat(i18n): add language switcher with en/ja translations
- New client-side i18n via React Context (useI18n, tArray, I18nProvider)
- Catalog ships 21 locale stubs; only zh-CN/en/ja have reviewed translations
- Header language switcher (globe icon + short label) before settings gear
- All hardcoded Chinese UI text migrated to keys: typewriter, options,
  hints (with embedded gear icon via dangerouslySetInnerHTML), settings
  panel, footer/about, play page hints
- AI output language follows user-selected locale via trailing one-liner
  directive appended to Architect/Writer/CharacterDesigner/InsertBeat
  user messages (preserves system-prompt cacheability)
- Per-locale separator rule: zh uses middot between every glyph; en/ja
  use plain spaces
- Option value → i18n key suffix maps preserve Chinese as the underlying
  identifier so analytics unions and STYLE_MAP keys stay byte-stable

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 16:54:35 +08:00

184 lines
5.8 KiB
Markdown

# InfiPlot i18n Implementation
## Summary
A complete i18n infrastructure has been implemented for InfiPlot, enabling support for 22 languages:
- English (en)
- Simplified Chinese (zh-CN) - Source language
- Traditional Chinese Taiwan (zh-TW)
- Traditional Chinese Hong Kong (zh-HK)
- Japanese (ja)
- Korean (ko)
- Spanish (es)
- French (fr)
- German (de)
- Portuguese Brazil (pt-BR)
- Portuguese (pt)
- Russian (ru)
- Italian (it)
- Vietnamese (vi)
- Thai (th)
- Indonesian (id)
- Turkish (tr)
- Polish (pl)
- Dutch (nl)
- Ukrainian (uk)
- Hindi (hi)
- Czech (cs)
## What Was Implemented
### 1. Core i18n Infrastructure (`lib/i18n/`)
- **config.ts**: Locale configuration, locale names, storage key management
- **types.ts**: TypeScript types for translation system
- **utils.ts**: Helper functions for nested value access, string formatting
- **client.tsx**: React context provider and `useI18n()` hook for client components
- **server.ts**: Server-side translation utilities for Next.js App Router
- **index.ts**: Main export file
### 2. Translation Files (`lib/i18n/locales/`)
- **zh-CN.ts**: Complete source translations (Chinese)
- **en.ts**: Reference English translations
- Additional locale files will be generated by the translation script
### 3. Translation Script (`scripts/translate-i18n.mjs`)
A Node.js script that:
- Reads the source zh-CN translation file
- Uses LLM APIs (Gemini or OpenAI-compatible) to translate to all target languages
- Preserves structure and handles special cases:
- Placeholder variables (`{{email}}`, `{n}`, etc.)
- HTML tags (`<em>`, `<a>`, etc.)
- Select/message format syntax
- Proper nouns (InfiPlot, GitHub, Google, etc.)
- Generates TypeScript locale files
- Updates client.tsx and server.ts imports automatically
Usage:
```bash
# With Gemini
node scripts/translate-i18n.mjs --provider gemini --api-key YOUR_KEY
# With OpenAI-compatible API
TEXT_API_KEY=your_key TEXT_BASE_URL=https://api.openai.com/v1 node scripts/translate-i18n.mjs --provider openai
```
### 4. Components Updated with i18n
- ✅ CustomForm.tsx
- ✅ DialogueHistoryModal.tsx
- ✅ AuthModal.tsx
- ✅ PlayCanvas.tsx
- ✅ SettingsModal.tsx
- ✅ page.tsx (home page)
- ✅ layout.tsx (I18nProvider wrapper)
- ✅ LanguageSwitcher.tsx (new component)
## Current Status
### Completed
1. **i18n Infrastructure** - All core files in `lib/i18n/`
2. **Translation Files** - zh-CN.ts (source) and en.ts (reference) complete
3. **Stub Files** - Created for all 20 target languages (fallback to en)
4. **Component Integration** - All UI components now use `t()` function
5. **Language Switcher** - Added to page header with dropdown UI
6. **TypeScript Types** - Full type safety for translation system
### Remaining Work
1. **Generate Actual Translations**
- Run the translation script to translate stub files
- Review and edit generated translations for quality
- Test with native speakers if possible
2. **Update Metadata** (optional)
- Make page titles and descriptions dynamic based on locale
- Update `lang` attribute on html element dynamically
### Optional Enhancements
1. **Server-Side Rendering Support**
- Implement locale detection from Accept-Language header
- Add middleware for locale routing (e.g., /en/play, /zh-CN/play)
- Cache translations for better performance
2. **Date/Number Formatting**
- Add locale-specific formatting for dates, numbers, currencies
- Use Intl.DateTimeFormat and Intl.NumberFormat
3. **RTL Support**
- Currently no RTL locales, but infrastructure is in place
- Add layout mirroring if needed for future RTL languages
4. **Pluralization**
- Enhance formatTranslation to support ICU message format
- Handle singular/plural forms
## Translation Best Practices
When adding new strings:
1. Keep strings neutral where possible
2. Avoid culturally-specific references
3. Provide context for translators in comments
4. Test with longer strings (German, Russian can be 2-3x longer)
5. Keep placeholders consistent (`{{varName}}` or `{varName}`)
## API Keys Required
To generate translations, set one of:
- `GEMINI_API_KEY` for Google Gemini (recommended for cost)
- `TEXT_API_KEY` for OpenAI-compatible API
- `TEXT_BASE_URL` for custom OpenAI-compatible endpoints
## Files Modified
### New Files Created
- `lib/i18n/` (entire directory)
- `config.ts` - Locale configuration
- `client.tsx` - React context provider
- `server.ts` - Server-side utilities
- `utils.ts` - Helper functions
- `locales/zh-CN.ts` - Source translations
- `locales/en.ts` - English reference
- `locales/zh-TW.ts` - Traditional Chinese stub
- `locales/zh-HK.ts` - Hong Kong Chinese stub
- `locales/ja.ts` - Japanese stub
- `locales/ko.ts` - Korean stub
- `locales/es.ts` - Spanish stub
- `locales/fr.ts` - French stub
- `locales/de.ts` - German stub
- `locales/pt-BR.ts` - Portuguese Brazil stub
- `locales/pt.ts` - Portuguese stub
- `locales/ru.ts` - Russian stub
- `locales/it.ts` - Italian stub
- `locales/vi.ts` - Vietnamese stub
- `locales/th.ts` - Thai stub
- `locales/id.ts` - Indonesian stub
- `locales/tr.ts` - Turkish stub
- `locales/pl.ts` - Polish stub
- `locales/nl.ts` - Dutch stub
- `locales/uk.ts` - Ukrainian stub
- `locales/hi.ts` - Hindi stub
- `locales/cs.ts` - Czech stub
- `components/LanguageSwitcher.tsx` - Language selector component
- `scripts/translate-i18n.mjs` - Translation script
- `docs/i18n-implementation.md` - This documentation
### Modified Files
- `app/layout.tsx` - Added I18nProvider wrapper
- `app/page.tsx` - Added i18n to all strings and LanguageSwitcher
- `components/CustomForm.tsx` - Added i18n
- `components/DialogueHistoryModal.tsx` - Added i18n
- `components/AuthModal.tsx` - Added i18n
- `components/PlayCanvas.tsx` - Added i18n
- `components/SettingsModal.tsx` - Added i18n
## TypeScript
All type definitions are in place. Run `pnpm typecheck` to verify.