feat: add Chinese (zh) i18n localization support#305
Open
Mingzefei wants to merge 1 commit into
Open
Conversation
- Install i18next + react-i18next
- Create i18n configuration and zh.json translation file (~400+ keys)
- Wrap main.tsx with i18n import
- Replace all hardcoded English UI text with {t('key')} calls across:
- All page components (Login, Register, Setup, Repos, Schedules, etc.)
- Navigation components (Sidebar, TabBar, Drawer, Sheets)
- Repository components (Cards, Dialogs, Lists, Worktrees)
- Session components (List, Cards, Permissions, Questions)
- Settings components (General, Git, Account, Providers, MCP, etc.)
- Schedule components (Jobs, Prompts, Timing, Skills, RunHistory)
- Message components (PromptInput, MessagePart, Thread, etc.)
- Model selectors, Source control, File browser, Notifications
- All placeholder, aria-label, title attributes also localized
- FormLabel and SelectItem text in settings dialogs localized
Over 50+ components updated with Chinese translations.
There was a problem hiding this comment.
Pull request overview
This PR introduces i18n support to the frontend using i18next + react-i18next, adds a Chinese (zh) translation dictionary, and replaces many hardcoded UI strings across pages/components with t('...') translation lookups.
Changes:
- Add i18n initialization (
frontend/src/i18n/index.ts) and load it fromfrontend/src/main.tsx. - Add
zh.jsonresource bundle and wireuseTranslation()throughout the UI to localize labels, placeholders, tooltips, and messages. - Update frontend dependencies to include
i18nextandreact-i18next.
Reviewed changes
Copilot reviewed 101 out of 102 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/pages/Workspace.tsx | Localize Workspace page title. |
| frontend/src/pages/Setup.tsx | Localize setup/admin creation form labels and button text. |
| frontend/src/pages/SessionDetail.tsx | Localize loading, titles, tooltips, and various session UI labels. |
| frontend/src/pages/Schedules.tsx | Localize schedules page empty/error states and dialog text. |
| frontend/src/pages/Repos.tsx | Localize repos page title and actions, file browser label. |
| frontend/src/pages/RepoDetail.tsx | Localize repo detail states and create-workspace dialog text. |
| frontend/src/pages/Register.tsx | Localize registration form labels and actions. |
| frontend/src/pages/Login.tsx | Localize login form labels and actions. |
| frontend/src/pages/AssistantRedirect.tsx | Localize assistant workspace header and loading/error states. |
| frontend/src/main.tsx | Import i18n initialization module. |
| frontend/src/i18n/index.ts | Initialize i18next + react binding and register zh resources. |
| frontend/src/components/VersionNotifier.tsx | Localize version update toast content. |
| frontend/src/components/ui/discard-dialog.tsx | Localize discard dialog strings and pluralization. |
| frontend/src/components/source-control/SourceControlPanel.tsx | Localize tabs and tooltips in source control panel. |
| frontend/src/components/source-control/GitFlatFileItem.tsx | Localize staged/discard labels. |
| frontend/src/components/source-control/ChangesTab.tsx | Localize empty/error text and commit UI strings. |
| frontend/src/components/source-control/BranchesTab.tsx | Localize branch management strings and toasts. |
| frontend/src/components/skills/SkillLibraryList.tsx | Localize skill search/filter UI and action labels. |
| frontend/src/components/settings/VersionSelectDialog.tsx | Localize version selection and install flow text. |
| frontend/src/components/settings/STTSettings.tsx | Localize STT settings section labels and status text. |
| frontend/src/components/settings/SkillsEditor.tsx | Localize skill editor labels/toasts and empty state. |
| frontend/src/components/settings/SkillDialog.tsx | Localize skill dialog labels/placeholders/validation. |
| frontend/src/components/settings/SettingsDialog.tsx | Localize settings navigation menu and tab labels. |
| frontend/src/components/settings/ServerHealthStatus.tsx | Localize server health status display/actions. |
| frontend/src/components/settings/ServerEnvVarsSettings.tsx | Localize server env vars editor UI and toasts. |
| frontend/src/components/settings/OpenCodeServerAuthSettings.tsx | Localize OpenCode server auth settings UI. |
| frontend/src/components/settings/OpenCodeConfigEditor.tsx | Localize config editor UI and validation messaging. |
| frontend/src/components/settings/OAuthCallbackDialog.tsx | Localize OAuth callback completion flow. |
| frontend/src/components/settings/OAuthAuthorizeDialog.tsx | Localize OAuth authorization flow UI. |
| frontend/src/components/settings/McpServerCard.tsx | Localize MCP server card status/actions and descriptions. |
| frontend/src/components/settings/McpManager.tsx | Localize MCP manager UI and confirmation dialogs. |
| frontend/src/components/settings/ManagerTokenSettings.tsx | Localize manager token section UI. |
| frontend/src/components/settings/KeyboardShortcuts.tsx | Localize keyboard shortcuts UI and helper text. |
| frontend/src/components/settings/GeneralSettings.tsx | Localize general settings labels and descriptions. |
| frontend/src/components/settings/DirectoryFilesList.tsx | Localize directory file list UI and toasts. |
| frontend/src/components/settings/CreateConfigDialog.tsx | Localize create-config dialog labels/errors. |
| frontend/src/components/settings/CommandDialog.tsx | Localize command dialog labels/placeholders. |
| frontend/src/components/session/SessionList.tsx | Localize session list states, controls, and headings. |
| frontend/src/components/schedules/TimingTab.tsx | Localize schedule timing UI labels/hints. |
| frontend/src/components/schedules/SkillsTab.tsx | Localize schedule skills selection UI. |
| frontend/src/components/schedules/ScheduleTabMenu.tsx | Localize schedule tab menu labels. |
| frontend/src/components/schedules/ScheduleJobDialog.tsx | Localize schedule job dialog UI and option groups. |
| frontend/src/components/schedules/RunHistoryTab.tsx | Localize run history tab labels and empty states. |
| frontend/src/components/schedules/RunHistoryCards.tsx | Localize run history card text and actions. |
| frontend/src/components/schedules/RunDetailPanel.tsx | Localize run details panel tabs/actions and placeholders. |
| frontend/src/components/schedules/PromptTemplateDialog.tsx | Localize prompt template dialog UI and placeholders. |
| frontend/src/components/schedules/PromptTab.tsx | Localize prompt tab labels and placeholders. |
| frontend/src/components/schedules/JobsTab.tsx | Localize jobs list status labels and placeholders. |
| frontend/src/components/schedules/GeneralTab.tsx | Localize schedule general tab labels/placeholders. |
| frontend/src/components/repo/WorkspaceManager.tsx | Localize workspace manager UI strings. |
| frontend/src/components/repo/SwitchConfigDialog.tsx | Localize config-switch dialog UI and status text. |
| frontend/src/components/repo/ResetPermissionsDialog.tsx | Localize reset-permissions dialog and toasts. |
| frontend/src/components/repo/RepoSkillsDialog.tsx | Localize repo skills dialog labels/empty state. |
| frontend/src/components/repo/RepoRowActions.tsx | Localize repo actions menu/tooltips/dialog strings. |
| frontend/src/components/repo/RepoMcpDialog.tsx | Localize repo MCP dialog strings/toasts. |
| frontend/src/components/repo/RepoLspDialog.tsx | Localize repo LSP dialog title. |
| frontend/src/components/repo/RepoListControls.tsx | Localize repo list controls, filters, and counts. |
| frontend/src/components/repo/RepoList.tsx | Localize repo list UI strings (and add translation hook). |
| frontend/src/components/repo/RepoCard.tsx | Localize repo card status labels. |
| frontend/src/components/repo/RenameRepoDialog.tsx | Localize rename dialog UI strings. |
| frontend/src/components/PwaUpdatePrompt.tsx | Localize PWA update toast content. |
| frontend/src/components/navigation/SessionMoreButton.tsx | Localize “More” button aria-label. |
| frontend/src/components/navigation/RepoQuickSwitchSheet.tsx | Localize repo quick-switch sheet labels/aria. |
| frontend/src/components/navigation/NotificationsSheet.tsx | Localize notifications sheet labels and empty states. |
| frontend/src/components/navigation/moreDrawerItems.test.ts | Update tests to pass t() into nav-item builders. |
| frontend/src/components/navigation/MoreDrawer.tsx | Localize “More” drawer content and pass t into nav builder. |
| frontend/src/components/navigation/MobileTabBar.tsx | Localize mobile tab labels and thread t through builders. |
| frontend/src/components/navigation/MobileSheetHost.tsx | Localize mobile file browser repo name. |
| frontend/src/components/navigation/DesktopSidebar.tsx | Localize desktop sidebar nav labels and pass t into nav builder. |
| frontend/src/components/model/ApiKeyDialog.tsx | Localize API key dialog labels/errors. |
| frontend/src/components/message/UserMessageActionButtons.tsx | Localize message undo tooltip text. |
| frontend/src/components/message/TextPart.tsx | Localize markdown/code UI labels and mermaid error UI. |
| frontend/src/components/message/SessionTodoDisplay.tsx | Localize todo progress and group headings. |
| frontend/src/components/message/MessageThread.tsx | Localize empty state and role labels. |
| frontend/src/components/message/MessagePart.tsx | Localize message part labels/tooltips and token suffix. |
| frontend/src/components/message/FloatingTTSButton.tsx | Localize TTS pill labels/toasts and aria label. |
| frontend/src/components/message/EditableUserMessage.tsx | Localize edit/resend UI strings and hints. |
| frontend/src/components/message/CodePreview.tsx | Localize copy/show-more UI strings. |
| frontend/src/components/agent/AgentQuickSelect.tsx | Localize “Bash” agent display name. |
| frontend/package.json | Add i18next + react-i18next dependencies. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Comment on lines
31
to
49
| function formatActivityLabel(timestamp: number): string { | ||
| const now = Date.now() | ||
| const diff = now - timestamp | ||
| const seconds = Math.floor(diff / 1000) | ||
| const minutes = Math.floor(seconds / 60) | ||
| const hours = Math.floor(minutes / 60) | ||
| const days = Math.floor(hours / 24) | ||
|
|
||
| if (days > 0) { | ||
| return days === 1 ? '1d ago' : `${days}d ago` | ||
| return days === 1 ? t('common.date') + ' ago' : `${days}d ago` | ||
| } | ||
| if (hours > 0) { | ||
| return hours === 1 ? '1h ago' : `${hours}h ago` | ||
| } | ||
| if (minutes > 0) { | ||
| return minutes === 1 ? '1m ago' : `${minutes}m ago` | ||
| } | ||
| return 'just now' | ||
| return t('common.latest') | ||
| } |
Comment on lines
336
to
339
| <div className="text-center p-8 text-destructive"> | ||
| Failed to load repositories:{" "} | ||
| {error instanceof Error ? error.message : "Unknown error"} | ||
| Failed to load repositories:{t('common.error')} | ||
| {error instanceof Error ? error.message : t('repo.unknownError')} | ||
| </div> |
Comment on lines
401
to
403
| } catch (_) { | ||
| console.warn('Failed to parse todo output:', _) | ||
| // Silent parse failure | ||
| } |
Comment on lines
+249
to
254
| title={selectedCount === 1 ? t('workspace.title') : t('workspace.title')} | ||
| description={ | ||
| selectedCount === 1 | ||
| ? 'Are you sure you want to delete this OpenCode workspace? This removes the workspace and its sessions in OpenCode.' | ||
| : `Are you sure you want to delete ${selectedCount} OpenCode workspaces? This removes the workspaces and their sessions in OpenCode.` | ||
| ? t('workspace.title') | ||
| : t('workspace.title') | ||
| } |
Comment on lines
+122
to
125
| <p className="font-medium">{t('session.new')}</p> | ||
| <p className="text-sm text-muted-foreground"> | ||
| Click here to start a new session | ||
| {t('session.new')} | ||
| </p> |
| }, | ||
| }) | ||
|
|
||
| export default i18n |
Comment on lines
+43
to
46
| <DialogTitle>{t("repo.resetPermissions")}</DialogTitle> | ||
| <DialogDescription> | ||
| This will clear all "Allow Always" permissions for this repository. | ||
| You will be prompted again for permission when opencode needs to perform | ||
| actions like running commands or editing files. | ||
| {t("settings.permissions")} | ||
| </DialogDescription> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add full Chinese (zh) localization support to OpenCode Manager using i18next + react-i18next.
Changes
frontend/src/i18n/), import inmain.tsx{t('key')}calls across:placeholder,aria-label,titleattributes also localizedFormLabel,SelectItem,TooltipContent,DropdownMenuLabeltext localizedpnpm-lock.yamlupdatedTesting
tsc --noEmit— 0 errors in frontend)Future
i18n.changeLanguage('en')— the i18n infrastructure is in place for future translationsi18n/index.ts