feat(i18n): Add frontend Chinese localization support#50
feat(i18n): Add frontend Chinese localization support#50vanch007 wants to merge 2 commits intoaudiohacking:mainfrom
Conversation
- 新增 i18n 配置和中英文翻译文件 (ui/i18n.ts, ui/locales/*.json) - 所有核心组件 i18n 化: - App.tsx - 音频播放错误消息 - Sidebar.tsx - 侧边栏导航 - CreatePanel.tsx - 创作面板 - LibraryView.tsx - 曲库视图 - Player.tsx - 播放器 - RightSidebar.tsx - 右侧边栏 - SettingsModal.tsx - 设置弹窗 - SongList.tsx - 歌曲列表 - SongProfile.tsx - 歌曲详情 - UserProfile.tsx - 用户资料 - TrainingPanel.tsx - 模型训练 - StemSplittingPanel.tsx - 音轨分离 - VoiceCloningPanel.tsx - 声音克隆 - MidiPanel.tsx - MIDI 工具 - SearchPage.tsx - 搜索页面 - 新增翻译模块: training/stem_splitting/voice_cloning/midi/search/console/genres/create_extra/vocal_languages - 支持浏览器语言自动检测和 localStorage 持久化 - 修复后端消息覆盖前端翻译的问题
There was a problem hiding this comment.
Pull request overview
Adds frontend internationalization (i18next/react-i18next) with English + Simplified Chinese resources, and wires core UI components to use translation keys with browser-language detection + localStorage persistence.
Changes:
- Added i18n initialization and injected it at app bootstrap (
ui/i18n.ts,ui/index.tsx). - Added EN/ZH locale JSON resource bundles (
ui/locales/en.json,ui/locales/zh.json). - Replaced many hardcoded UI strings across core panels/components with
t(...)calls.
Reviewed changes
Copilot reviewed 20 out of 22 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/package.json | Adds i18next/react-i18next + browser language detector dependencies. |
| ui/package-lock.json | Locks new dependency tree for i18n packages. |
| ui/i18n.ts | Initializes i18next with EN/ZH resources + detection/persistence. |
| ui/index.tsx | Imports i18n init module at app startup. |
| ui/locales/en.json | English translation keys for UI text. |
| ui/locales/zh.json | Simplified Chinese translation keys for UI text. |
| ui/App.tsx | Localizes toast/error messages and a few UI labels. |
| ui/components/* | Broad replacement of UI strings with translation keys across panels/views. |
| .gitignore | Ignores checkpoints/ directory. |
Files not reviewed (1)
- ui/package-lock.json: Language not supported
Comments suppressed due to low confidence (1)
ui/components/CreatePanel.tsx:1710
- Several user-facing strings in this header are still hardcoded (the
InfoTooltiptext and the helper line “Genre, mood, instruments, vibe”). Since this PR is internationalizing the UI, these should be moved into translation keys (e.g.create.tooltips.*/create_extra.*) so the Custom mode matches the rest of the localized UI.
<span className="text-xs font-bold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide">{t('create.inputs.style_of_music')}</span>
<InfoTooltip text={(taskType === 'cover' || taskType === 'audio2audio') ? 'Target style for the cover (genre, mood, instruments). Lower Cover Strength gives this more influence over the source.' : 'Genre, mood, instruments, vibe. Same as Simple mode — switching tabs keeps this text.'} />
</span>
<p className="text-[11px] text-zinc-400 dark:text-zinc-500 mt-0.5">Genre, mood, instruments, vibe</p>
</div>
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| value={lyrics} | ||
| onChange={(e) => setLyrics(e.target.value)} | ||
| placeholder={instrumental ? "Instrumental mode - no lyrics needed" : "[Verse]\nYour lyrics here...\n\n[Chorus]\nThe catchy part..."} | ||
| placeholder={instrumental ? "Instrumental mode - no lyrics needed" : t('create.inputs.lyrics_placeholder')} |
There was a problem hiding this comment.
The lyrics textarea placeholder uses a hardcoded English string when instrumental is true ("Instrumental mode - no lyrics needed"). This should be translated (or reused from an existing key) so placeholders are consistent with the selected locale.
| placeholder={instrumental ? "Instrumental mode - no lyrics needed" : t('create.inputs.lyrics_placeholder')} | |
| placeholder={t('create.inputs.lyrics_placeholder')} |
| import i18n from 'i18next'; | ||
| import { initReactI18next } from 'react-i18next'; | ||
| import LanguageDetector from 'i18next-browser-languagedetector'; | ||
|
|
There was a problem hiding this comment.
i18n.ts imports JSON translation files, but the current ui/tsconfig.json does not enable resolveJsonModule and there is no declare module '*.json' in the project. This will typically fail TypeScript type-checking with “Cannot find module '*.json'”. Add resolveJsonModule (and usually allowSyntheticDefaultImports) to tsconfig, or add a .d.ts module declaration for JSON imports.
| declare module './locales/en.json' { | |
| const value: any; | |
| export default value; | |
| } | |
| declare module './locales/zh.json' { | |
| const value: any; | |
| export default value; | |
| } |
| <option value="auto">{t('stem_splitting.device_auto')}</option> | ||
| <option value="mps">{t('stem_splitting.device_mps')}</option> | ||
| <option value="cpu">{t('stem_splitting.device_cpu')}</option> |
There was a problem hiding this comment.
The device option labels are pulled from stem_splitting.* translation keys. This creates cross-feature coupling and makes it harder to adjust wording for voice cloning independently. Prefer adding voice_cloning.device_auto/device_mps/device_cpu keys and referencing those here.
| <option value="auto">{t('stem_splitting.device_auto')}</option> | |
| <option value="mps">{t('stem_splitting.device_mps')}</option> | |
| <option value="cpu">{t('stem_splitting.device_cpu')}</option> | |
| <option value="auto">{t('voice_cloning.device_auto')}</option> | |
| <option value="mps">{t('voice_cloning.device_mps')}</option> | |
| <option value="cpu">{t('voice_cloning.device_cpu')}</option> |
| <span className="text-xs font-bold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide">{t('create.inputs.lyrics')}</span> | ||
| <InfoTooltip text={(taskType === 'cover' || taskType === 'audio2audio') ? 'Target lyrics for the cover. Uncheck Instrumental to use them. Lower Cover Strength gives your lyrics more influence.' : 'Lyric content and structure. Use [Verse], [Chorus], etc. Leave empty or use Instrumental for no vocals.'} /> | ||
| </span> | ||
| <p className="text-[11px] text-zinc-400 dark:text-zinc-500 mt-0.5">Leave empty for instrumental or switch to Instrumental below</p> | ||
| <p className="text-[11px] text-zinc-400 dark:text-zinc-400 mt-0.5">Leave empty for instrumental or switch to Instrumental below</p> | ||
| </div> |
There was a problem hiding this comment.
The lyrics section still contains hardcoded English strings (the InfoTooltip text and the hint “Leave empty for instrumental or switch to Instrumental below”). To avoid mixed-language UI after switching locales, move these to translation keys (there is already create_extra.lyrics_hint in the locale files).
| @@ -1,9 +1,10 @@ | |||
| import React, { useState, useEffect } from 'react'; | |||
| import { X, User as UserIcon, Palette, Info, Edit3, ExternalLink, Github, FolderOpen, HardDrive, ZoomIn, Box } from 'lucide-react'; | |||
| import { X, User as UserIcon, Palette, Info, Edit3, ExternalLink, Github, FolderOpen, HardDrive, ZoomIn, Box, Globe } from 'lucide-react'; | |||
There was a problem hiding this comment.
Unused import FolderOpen.
| import { X, User as UserIcon, Palette, Info, Edit3, ExternalLink, Github, FolderOpen, HardDrive, ZoomIn, Box, Globe } from 'lucide-react'; | |
| import { X, User as UserIcon, Palette, Info, Edit3, ExternalLink, Github, HardDrive, ZoomIn, Box, Globe } from 'lucide-react'; |
Added i18n configuration and Chinese/English translation files (ui/i18n.ts, ui/locales/*.json)
Internationalized all core components:
App.tsx - Audio playback error messages
Sidebar.tsx - Sidebar navigation
CreatePanel.tsx - Creation panel
LibraryView.tsx - Library view
Player.tsx - Player
RightSidebar.tsx - Right sidebar
SettingsModal.tsx - Settings modal
SongList.tsx - Song list
SongProfile.tsx - Song details
UserProfile.tsx - User profile
TrainingPanel.tsx - Model training
StemSplittingPanel.tsx - Stem splitting
VoiceCloningPanel.tsx - Voice cloning
MidiPanel.tsx - MIDI tools
SearchPage.tsx - Search page
Added translation modules: training/stem_splitting/voice_cloning/midi/search/console/genres/create_extra/vocal_languages
Supported automatic browser language detection and localStorage persistence
Fixed the issue where backend messages were overriding frontend translations