add i18n feat && Add partial translation

This commit is contained in:
YuanNiancai
2026-01-16 19:11:19 +08:00
parent 42b2d5e1d9
commit 4216676395
32 changed files with 3934 additions and 220 deletions

View File

@@ -0,0 +1,246 @@
# Design: i18n Implementation Architecture
## Context
Claude Code UI is a React-based web application with ~50 components, currently serving English-speaking users only. The application uses:
- React 18 with functional components and hooks
- Context-based state management (AuthContext, ThemeContext, etc.)
- localStorage for user preferences
- Vite for bundling
**Constraints:**
- Must not impact performance (bundle size, runtime overhead)
- Must support hot-reload during development
- Must allow switching language without page reload
- Must be extensible for additional languages in the future
**Stakeholders:**
- End users: Need intuitive language switching
- Developers: Need easy translation management workflow
- Maintainers: Need to keep translations synchronized
## Goals / Non-Goals
**Goals:**
1. Implement production-ready i18n using `react-i18next`
2. Support English (en) and Simplified Chinese (zh-CN) in Phase 1
3. Provide language selector in Settings > Account
4. Store user language preference in localStorage
5. Extract and translate top 100 most common UI strings in Phase 1
6. Create reusable translation namespace structure
**Non-Goals:**
1. Translate AI-generated content (chat messages, code responses)
2. Translate backend error logs or terminal output
3. Implement server-side translation
4. Create translation management web UI
5. Add RTL (Right-to-Left) language support
## Decisions
### Decision 1: Use react-i18next Library
**Rationale:**
- Industry-standard for React internationalization (2.5M weekly downloads)
- Built-in hooks (`useTranslation`) compatible with React 18
- Supports interpolation, plurals, date/number formatting
- Excellent TypeScript support (even though we use JS)
- Lazy-loading and code-splitting for translations
- Active community and long-term viability
**Alternatives Considered:**
- **Format.js (React Intl)**: More complex setup, larger bundle size
- **Lingui**: Compile-time approach, requires Babel plugin, over-engineering for our needs
- **Custom solution**: Would require building interpolation, plurals, date formatting from scratch
### Decision 2: Namespace-Based Translation Structure
**Structure:**
```
src/i18n/
├── locales/
│ ├── en/
│ │ ├── common.json # Shared UI strings
│ │ ├── settings.json # Settings page
│ │ ├── auth.json # Login/Auth
│ │ └── sidebar.json # Navigation/Sidebar
│ └── zh-CN/
│ ├── common.json
│ ├── settings.json
│ ├── auth.json
│ └── sidebar.json
├── config.js # i18next configuration
└── ReactSuspense.js # Lazy-loading wrapper
```
**Rationale:**
- Namespace-based approach aligns with feature boundaries
- Smaller files = easier to manage translations
- Supports code-splitting (load only needed namespaces)
- Scalable for future languages
### Decision 3: Language Preference Storage in localStorage
**Rationale:**
- Consistent with existing preferences (theme, code editor settings)
- No backend changes required
- Instant sync across tabs
- Works in offline mode
**Storage Key:** `userLanguage`
**Default Value:** `'en'` (English)
**Valid Values:** `'en'`, `'zh-CN'`
### Decision 4: Translation Key Naming Convention
**Pattern:** `{namespace}.{component}.{element}.{state}`
**Examples:**
- `common.buttons.save` → "Save"
- `common.buttons.cancel` → "Cancel"
- `settings.account.language.label` → "Language"
- `auth.login.title` → "Sign In"
- `sidebar.projects.new` → "New Project"
**Rationale:**
- Hierarchical structure mirrors component tree
- Easy to locate translation key in code
- Prevents naming collisions across namespaces
- Self-documenting
### Decision 5: Fallback Strategy
**Fallback Chain:**
1. User's selected language (e.g., `zh-CN`)
2. English (`en`) as default fallback
3. Return translation key if not found in any language
**Configuration:**
```javascript
fallbackLng: 'en',
debug: false, // Set true in development to log missing keys
saveMissing: false, // Don't auto-create missing keys (manual review required)
```
**Rationale:**
- English is source language, guaranteed to have all keys
- Showing translation key in production is better than blank text
- Manual review prevents typo propagation
## Risks / Trade-offs
### Risk 1: Bundle Size Increase
**Impact:** Initial bundle may increase by ~30KB (gzip) for react-i18next + translations
**Mitigation:**
- Use code-splitting to load translations per namespace
- Enable tree-shaking for unused languages
- Target Phase 1: Top 100 strings only
**Monitoring:**
```bash
npm run build
# Check dist/ size before/after
```
### Risk 2: Missing Translations at Runtime
**Impact:** Users may see English text mixed with Chinese
**Mitigation:**
- Use `useTranslation` with `{ fallbackLng: 'en' }`
- Implement `missingKeyHandler` to log missing keys in development
- Create translation coverage report in CI
### Risk 3: Translation Synchronization Debt
**Impact:** New features may forget to add translations
**Mitigation:**
- Add ESLint rule to detect hardcoded strings in JSX
- Include i18n checklist in PR template
- Document translation workflow in CLAUDE.md
### Risk 4: Context-Aware Translations
**Example:** "Save" could mean:
- Save file (保存文件)
- Save money (节省)
- Rescue (救援)
**Mitigation:**
- Use descriptive keys: `common.buttons.saveFile` vs `common.buttons.saveMoney`
- Add context comments for translators: `{{context}} "Save file to disk"`
## Migration Plan
### Phase 1: Infrastructure Setup (Day 1)
1. Install `react-i18next` and `i18next`
2. Create `src/i18n/` directory structure
3. Configure i18next with lazy-loading
4. Add I18nextProvider to App.jsx
5. Create translation resource files (en, zh-CN)
### Phase 2: Core UI Translation (Day 2-3)
**Priority Order:**
1. Common buttons and labels (Save, Cancel, Delete, Create)
2. Navigation elements (Settings, menus)
3. Settings page
4. Auth/Login pages
5. Sidebar labels
**Process per component:**
1. Replace hardcoded strings with `useTranslation()` hook
2. Add translation key to JSON files
3. Verify English still works
4. Add Chinese translation
5. Test language switching
### Phase 3: Language Selector (Day 3)
1. Add language dropdown to `AccountContent.jsx`
2. Implement `changeLanguage()` handler
3. Save preference to localStorage
4. Test reload persistence
### Phase 4: Validation (Day 4)
1. Manual testing of all translated components
2. Check for missing keys (console warnings)
3. Test language switching in both directions
4. Verify localStorage persistence
5. Test mobile responsive layout with longer Chinese text
### Rollback Plan
If critical issues arise:
1. Revert to commit before i18n changes
2. Keep translation files for future retry
3. Document blockers for next attempt
**Rollback Command:**
```bash
git revert <i18n-commit-hash>
npm install
```
## Open Questions
1. **Should we add TypeScript support for translations?**
- Current: No, project uses JavaScript
- Future consideration: Migrate to TypeScript for better type safety
2. **Should we integrate with translation management platform (e.g., Crowdin, Lokalise)?**
- Current decision: No, manual JSON editing is sufficient for 2 languages
- Future: Consider when adding 3+ languages or external translators
3. **Should we format dates and numbers according to locale?**
- Current decision: No, keep ISO format for simplicity
- Future: Use `i18next-intlplural` if users request localized dates
4. **How to handle pluralization in Chinese (which doesn't have plurals)?**
- Solution: Use same translation for singular/plural forms
- Example: `"1 file"``"1 个文件"`, `"2 files"``"2 个文件"`

View File

@@ -0,0 +1,51 @@
# Change: Add i18n Internationalization Support
## Why
The application currently has all UI text hardcoded in English, which limits accessibility for non-English speaking users. Adding internationalization (i18n) support will enable the application to serve a broader user base, particularly Chinese-speaking users who form a significant portion of the AI development community. This will improve user experience and adoption by allowing users to interact with the application in their preferred language.
## What Changes
- **BREAKING**: Add `react-i18next` dependency and configure i18n infrastructure
- Add `I18nextProvider` wrapper in App.jsx
- Create translation resource files for English (en) and Simplified Chinese (zh-CN)
- Extract and translate core UI text (menus, buttons, labels, error messages)
- Add language selector in Settings > Account section
- Store user language preference in localStorage
- Implement language switching without page reload
- Create translation namespace structure for scalable management
**Scope - Phase 1 (Progressive Translation):**
- Navigation elements (Settings, menus, buttons)
- Common UI labels (Save, Cancel, Delete, Create, Loading, Error messages)
- Settings page labels and descriptions
- Login/Auth related text
- Sidebar labels (Projects, Sessions, Files)
**Out of Scope - Phase 1:**
- AI-generated content (chat messages, responses)
- Developer-facing error logs
- Documentation and help text
- Terminal/shell output
## Impact
- **Affected specs:**
- `i18n` (NEW capability) - Internationalization system
- `user-interface` (NEW capability) - Language-aware UI components
- **Affected code:**
- `src/main.jsx` - Add i18n initialization
- `src/App.jsx` - Wrap with I18nextProvider
- `src/components/Settings.jsx` - Add language selector
- `src/components/settings/AccountContent.jsx` - Language preference UI
- All UI components - Replace hardcoded text with translation keys
- `src/i18n/` (NEW) - Translation resources and configuration
- `package.json` - Add react-i18next dependency
- **Affected database:** None (language preference stored in localStorage)
- **Migration:**
- No data migration required
- Default language: English (fallback for missing translations)
- User preference stored in `localStorage.getItem('userLanguage')`

View File

@@ -0,0 +1,202 @@
# i18n Capability Specification (Delta)
## ADDED Requirements
### Requirement: Translation Infrastructure
The system SHALL provide internationalization (i18n) infrastructure using react-i18next library to support multiple languages for user-facing text.
#### Scenario: Initialize i18n on application startup
- **WHEN** the application starts
- **THEN** the system SHALL initialize i18next with configuration
- **AND** load translation resources for English (en) and Chinese (zh-CN)
- **AND** set default language to English
- **AND** detect saved language preference from localStorage
#### Scenario: Load translation namespaces lazily
- **WHEN** a component requires translations
- **THEN** the system SHALL load only the required namespace (e.g., 'common', 'settings')
- **AND** cache loaded namespaces for subsequent access
- **AND** show loading state only during initial load
### Requirement: Language Selection and Persistence
The system SHALL allow users to select their preferred language and persist this preference across sessions.
#### Scenario: User selects language in Settings
- **WHEN** user navigates to Settings > Account > Language selector
- **THEN** the system SHALL display available languages: English and 简体中文
- **AND** show currently selected language as default
- **AND** allow user to change selection
#### Scenario: System saves language preference
- **WHEN** user selects a new language from dropdown
- **THEN** the system SHALL immediately change application language
- **AND** save selection to `localStorage.setItem('userLanguage', '<language>')`
- **AND** refresh all translated components without page reload
#### Scenario: System restores language preference on startup
- **WHEN** user returns to application after closing
- **THEN** the system SHALL read `localStorage.getItem('userLanguage')`
- **AND** initialize i18n with saved language
- **AND** default to English if no preference is saved
### Requirement: Translation Resource Structure
The system SHALL organize translation resources in namespace-based JSON files under `src/i18n/locales/{language}/`.
#### Scenario: Translation file organization
- **WHEN** developers add new translations
- **THEN** translations SHALL be organized by namespace: `common.json`, `settings.json`, `auth.json`, `sidebar.json`
- **AND** each namespace SHALL contain hierarchical keys with dot notation
- **AND** each key SHALL have corresponding translations in all supported languages
**Example structure:**
```json
{
"buttons": {
"save": "Save",
"cancel": "Cancel",
"delete": "Delete"
},
"status": {
"loading": "Loading...",
"success": "Success",
"error": "Error"
}
}
```
#### Scenario: Translation key naming convention
- **WHEN** developers create new translation keys
- **THEN** keys SHALL follow pattern: `{namespace}.{component}.{element}.{state}`
- **AND** use descriptive names to avoid ambiguity
- **AND** avoid abbreviations except for common UI terms (btn, lbl, msg)
**Examples:**
- `common.buttons.save`
- `settings.account.language.label`
- `auth.login.title`
- `btn.save` ✗ (too generic)
- `msg` ✗ (too vague)
### Requirement: Fallback Translation Strategy
The system SHALL provide fallback translations when a translation key is missing in the user's preferred language.
#### Scenario: Missing translation in selected language
- **WHEN** a translation key does not exist in Chinese (zh-CN)
- **THEN** the system SHALL fall back to English (en) translation
- **AND** log warning in development console
- **AND** display English text to user
#### Scenario: Missing translation in all languages
- **WHEN** a translation key does not exist in any language
- **THEN** the system SHALL display the translation key itself (e.g., `common.buttons.save`)
- **AND** log error in development console
- **AND** NOT break the application or crash
### Requirement: Component Translation Integration
The system SHALL provide React components and hooks for translating UI text.
#### Scenario: Functional component uses useTranslation hook
- **WHEN** a functional component needs translations
- **THEN** the component SHALL use `useTranslation()` hook from react-i18next
- **AND** specify namespace: `useTranslation('common')`
- **AND** call `t()` function with translation key
- **AND** automatically re-render when language changes
**Example:**
```javascript
import { useTranslation } from 'react-i18next';
function SaveButton() {
const { t } = useTranslation('common');
return <button>{t('buttons.save')}</button>;
}
```
#### Scenario: Component with interpolation
- **WHEN** a translation contains dynamic values (e.g., username, file count)
- **THEN** the translation SHALL use interpolation syntax: `{{variableName}}`
- **AND** the component SHALL pass variables to `t()` function
- **AND** the system SHALL insert values into translated string
**Example:**
```json
{
"welcome": "Welcome, {{username}}!",
"fileCount": "You have {{count}} files"
}
```
```javascript
const { t } = useTranslation('common');
t('welcome', { username: 'Alice' }); // "Welcome, Alice!"
t('fileCount', { count: 5 }); // "You have 5 files"
```
### Requirement: Excluded Content from Translation
The system SHALL NOT translate certain types of content to preserve accuracy and developer experience.
#### Scenario: AI-generated content remains untranslated
- **WHEN** AI assistant generates chat messages, code, or responses
- **THEN** the content SHALL remain in original language (usually English)
- **AND** NOT be processed by translation system
#### Scenario: Developer-facing logs remain in English
- **WHEN** the application logs errors, warnings, or debug information
- **THEN** log messages SHALL remain in English
- **AND** NOT be translated to maintain debugging consistency
#### Scenario: Terminal/shell output remains as-is
- **WHEN** the application displays terminal or shell output
- **THEN** the output SHALL remain in original language
- **AND** NOT be modified by translation system
### Requirement: Performance and Bundle Size
The system SHALL minimize the impact of i18n on application bundle size and runtime performance.
#### Scenario: Code-splitting for translation files
- **WHEN** the application is built for production
- **THEN** translation files SHALL be split by language and namespace
- **AND** loaded only when needed (lazy-loading)
- **AND** increase bundle size by less than 50KB (gzip)
#### Scenario: No performance regression on language switch
- **WHEN** user changes language preference
- **THEN** the system SHALL update UI within 100ms
- **AND** NOT require full page reload
- **AND** maintain smooth user experience
### Requirement: Developer Experience
The system SHALL provide tools and guidelines for contributors to add and maintain translations.
#### Scenario: Detecting missing translations in development
- **WHEN** a developer references a non-existent translation key
- **THEN** the system SHALL log warning in browser console
- **AND** display translation key in UI with warning styling
- **AND** NOT break the build process
#### Scenario: Documentation for contributors
- **WHEN** a contributor needs to add new translations
- **THEN** CLAUDE.md SHALL document i18n workflow
- **AND** provide examples of correct translation key usage
- **AND** list translation naming conventions
- **AND** explain how to add new languages
## MODIFIED Requirements
*N/A - This is a new capability, no existing requirements are modified.*
## REMOVED Requirements
*N/A - This is a new capability, no existing requirements are removed.*
## RENAMED Requirements
*N/A - This is a new capability, no existing requirements are renamed.*

View File

@@ -0,0 +1,176 @@
# User Interface Capability Specification (Delta)
## ADDED Requirements
### Requirement: Language-Aware UI Components
All user-facing UI components SHALL support internationalization and display translated text based on user's language preference.
#### Scenario: Settings page displays translated labels
- **WHEN** user opens Settings page
- **THEN** all section labels (Account, Permissions, MCP Servers, Appearance) SHALL be translated
- **AND** button labels (Save, Cancel, Delete) SHALL be translated
- **AND** description text SHALL be translated
- **AND** technical terms (e.g., JWT, API, SSH) may remain in English if no common translation exists
#### Scenario: Sidebar displays translated navigation
- **WHEN** user views sidebar navigation
- **THEN** section headers (Projects, Sessions) SHALL be translated
- **AND** action buttons (New Project, Refresh, Settings) SHALL be translated
- **AND** status messages (Loading, Error) SHALL be translated
#### Scenario: Login form displays translated text
- **WHEN** user views login form
- **THEN** form labels (Username, Password) SHALL be translated
- **AND** button text (Sign In, Create Account) SHALL be translated
- **AND** validation messages (Invalid credentials, Required field) SHALL be translated
- **AND** error messages SHALL be translated
#### Scenario: File operations show translated prompts
- **WHEN** user performs file operations (Save, Delete, Rename)
- **THEN** confirmation dialogs SHALL be translated
- **AND** success messages SHALL be translated
- **AND** error messages SHALL be translated
### Requirement: Language Selector in Settings
The Settings > Account section SHALL provide a language selector dropdown allowing users to choose their preferred language.
#### Scenario: Language selector displays current language
- **WHEN** user navigates to Settings > Account
- **THEN** a language selector dropdown SHALL be visible
- **AND** display label: "Language" (or translated equivalent)
- **AND** show currently selected language as default value
- **AND** list available options: English, 简体中文
#### Scenario: Language selector updates preference
- **WHEN** user selects a different language from dropdown
- **THEN** the system SHALL immediately change application language
- **AND** show loading indicator if translations are being loaded
- **AND** refresh all UI components with new language
- **AND** save preference to localStorage
- **AND** display success message: "Language changed successfully"
#### Scenario: Language selector persists across sessions
- **WHEN** user returns to application after closing
- **THEN** the language selector SHALL display the previously selected language
- **AND** the application UI SHALL be in the selected language
- **AND** the selector SHALL not show "Language" as default if user previously chose Chinese
### Requirement: Responsive Layout for Translated Text
UI components SHALL accommodate varying text lengths across languages without breaking layout or readability.
#### Scenario: Chinese text fits in buttons
- **WHEN** UI is displayed in Chinese (which often has longer text than English)
- **THEN** buttons SHALL expand to fit translated text
- **AND** text SHALL NOT overflow or wrap awkwardly
- **AND** button heights SHALL remain consistent
#### Scenario: Mobile layout handles longer translations
- **WHEN** application is viewed on mobile device with Chinese language
- **THEN** navigation menus SHALL accommodate longer text labels
- **AND** sidebar items SHALL not truncate important text
- **AND** layout SHALL remain responsive and touch-friendly
#### Scenario: Tables and lists maintain alignment
- **WHEN** table headers or list items are translated
- **THEN** column widths SHALL adjust to fit translated content
- **AND** text alignment SHALL remain appropriate (left-to-right for both languages)
- **AND** content SHALL remain readable without horizontal scrolling
### Requirement: Error and Status Messages
All error messages, success notifications, and status indicators SHALL be translated to provide clear feedback in user's preferred language.
#### Scenario: Error messages are translated
- **WHEN** an error occurs (e.g., network failure, validation error)
- **THEN** error message SHALL be displayed in user's selected language
- **AND** technical error codes MAY remain in English
- **AND** suggestions for resolution SHALL be translated
#### Scenario: Success notifications are translated
- **WHEN** an operation completes successfully (e.g., file saved, settings updated)
- **THEN** success message SHALL be displayed in user's selected language
- **AND** action buttons in notification (e.g., "Dismiss") SHALL be translated
#### Scenario: Loading states are translated
- **WHEN** application shows loading indicator
- **THEN** loading text SHALL be in user's selected language (e.g., "Loading..." vs "加载中...")
- **AND** progress messages SHALL be translated
#### Scenario: Validation messages are translated
- **WHEN** user submits form with invalid data
- **THEN** validation error SHALL be in user's selected language
- **AND** field-specific hints SHALL be translated
- **AND** placeholder text SHALL be translated
### Requirement: Accessibility with Translations
Translated UI SHALL maintain accessibility standards including screen reader compatibility and keyboard navigation.
#### Scenario: Screen readers announce translated text
- **WHEN** screen reader user navigates UI
- **THEN** screen reader SHALL announce translated text correctly
- **AND** language attribute SHALL be set on HTML element: `<html lang="zh-CN">`
- **AND** dynamic language changes SHALL update lang attribute
#### Scenario: Keyboard navigation works with translated labels
- **WHEN** user navigates with keyboard
- **THEN** all interactive elements SHALL be accessible via Tab key
- **AND** focus indicators SHALL be visible regardless of text length
- **AND** keyboard shortcuts SHALL work consistently across languages
### Requirement: Date and Number Formatting
The system SHALL format dates, numbers, and other locale-specific data according to user's language preference.
#### Scenario: Dates are formatted for locale
- **WHEN** application displays dates (e.g., file modification time, session creation time)
- **THEN** dates SHALL be formatted according to locale conventions
- **AND** Chinese users see: 2025年1月16日
- **AND** English users see: January 16, 2025
#### Scenario: Numbers are formatted for locale
- **WHEN** application displays numbers (e.g., token usage, file sizes)
- **THEN** numbers SHALL use appropriate digit grouping symbols
- **AND** Chinese users see: 1,234 (comma separator)
- **AND** decimal separators match locale preference
#### Scenario: File sizes are human-readable
- **WHEN** application displays file sizes
- **THEN** sizes SHALL be formatted with appropriate units (KB, MB, GB)
- **AND** unit labels SHALL be translated (e.g., "KB" vs "千字节")
- **AND** formatting shall be consistent across languages
## MODIFIED Requirements
### Requirement: Settings Page Navigation
The Settings page SHALL provide tabs for Account, Permissions, MCP Servers, and Appearance settings. All tab labels, section headers, and descriptions SHALL be translated based on user's language preference. The Account tab SHALL include a language selector dropdown that allows users to choose between English and Simplified Chinese.
#### Scenario: Navigate Settings with translated labels
- **WHEN** user opens Settings page
- **THEN** all navigation elements SHALL be in user's selected language
- **AND** tab labels SHALL be translated (Account → 账户, Permissions → 权限)
- **AND** active tab SHALL be visually indicated
- **AND** language selector SHALL be visible in Account tab
### Requirement: Onboarding Flow
New users SHALL see onboarding wizard explaining application features. All onboarding text, instructions, and button labels SHALL be translated based on user's language preference. The wizard SHALL automatically detect user's system language when possible.
#### Scenario: Onboarding in selected language
- **WHEN** new user first launches application
- **THEN** onboarding wizard SHALL detect system language or default to English
- **AND** all wizard text SHALL be translated
- **AND** user may change language during onboarding via language selector
- **AND** language preference SHALL persist after onboarding completes
## REMOVED Requirements
*N/A - No requirements are removed, only enhanced with i18n support.*
## RENAMED Requirements
*N/A - No requirements are renamed.*