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

5.8 KiB

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:

# 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.