# 10 — i18n 策略 ## 10.1 支援語言 | Locale | 顯示名稱 | 備註 | |--------|---------|------| | `zh-TW` | 繁體中文 | 主要語言,所有文案以此為準 | | `en` | English | 次要語言,從繁中翻譯 | **不支援**:簡體中文、日文、韓文、其他。如有需求另議。 ## 10.2 預設策略 **跟隨系統 locale**: ``` 系統 locale 偵測流程: 1. 讀取 Wails runtime 提供的系統語言 2. 若為 zh-* (zh-TW, zh-HK, zh-CN) → 使用 zh-TW 3. 其他 → 使用 en 4. 使用者若在 Settings 手動設定,則以手動為準 ``` **儲存位置**:資料目錄下 `config.json` 的 `locale` 欄位。各平台資料目錄見 `06-cross-platform.md §6.7`(macOS 為 `~/Library/Application Support/visiona-local/config.json`,第四輪 R4-5 全小寫)。 ## 10.3 實作技術 **沿用原 edge-ai-platform 的 i18n 方案**:`react-i18next`(原專案已有 `useTranslation` hook)。 ``` frontend/ ├─ src/locales/ │ ├─ zh-TW/ │ │ ├─ common.json ← 按鈕、通用詞 │ │ ├─ dashboard.json │ │ ├─ models.json │ │ ├─ devices.json │ │ ├─ workspace.json │ │ ├─ settings.json │ │ ├─ first-run.json │ │ └─ errors.json │ └─ en/ │ └─ (同上結構) └─ src/lib/i18n.ts ← i18next 初始化 ``` ## 10.4 命名慣例 - 命名空間:按頁面或功能區塊(`dashboard`, `models`, `first-run`) - Key 結構:`namespace:section.key` - 例:`first-run:welcome.title`、`common:button.continue` ## 10.5 關鍵詞彙統一表 | 繁中 | English | 備註 | |------|---------|------| | 裝置 | Device | 不用「設備」 | | 模型 | Model | — | | 推論 | Inference | 不用「推理」 | | 攝影機 | Camera | — | | 工作區 | Workspace | — | | 儀表板 | Dashboard | 主區塊直接稱「Dashboard」 | | 設定 | Settings | 不用「偏好設定」 | | 真實硬體模式 | Real Hardware | — | | Mock 模式 | Mock Mode | 中文版也保留 Mock,不翻「模擬」 | | 連接 | Connect | 動詞 | | 連線 | Connected | 狀態形容詞 | | 掃描 | Scan | — | | 載入 | Load | — | | 儲存 | Save | 不用「保存」 | | 刪除 | Delete | — | | 確定 | OK / Confirm | — | | 取消 | Cancel | — | | 關閉 | Close | — | | 略過 | Skip | — | ## 10.6 特殊狀況 ### 數字與單位 - 時間:使用 locale 預設格式(`Intl.DateTimeFormat`) - 檔案大小:統一用 `KB / MB / GB`(不翻譯) - 百分比:`92%`(不翻譯) - FPS、ms 等技術單位:不翻譯 ### 日期時間 - 繁中:`2026/04/11 14:30`(ISO 風格) - English:`Apr 11, 2026, 2:30 PM` ### 複數 英文需要處理單複數: ```json { "devices.count_one": "{{count}} device", "devices.count_other": "{{count}} devices" } ``` 中文不需要處理。 ## 10.7 Settings 語言切換 UX ``` ┌─ 一般 ────────────────────────┐ │ │ │ 語言 [繁體中文 ▾] │ │ │ │ 選項: │ │ • 跟隨系統(目前:繁中) │ │ • 繁體中文 │ │ • English │ └────────────────────────────────┘ ``` **切換行為**: > ⚠️ **M1 與 M2 差異(與 Architect 對齊)**:**即時切換是 M2 才做**。M1 先以「切換 → 寫入 config.json → 彈 toast 提示『請重啟 App 套用新語言』」的簡化流程上線,避免 M1 就要處理 `react-i18next` 全域 re-render、原生 menu bar 動態重建、錯誤文案快取失效等複雜度。 **M1(簡化版)**: - 使用者在 Settings > 一般 選擇語言 → 寫入 `config.json` 的 `locale` → 顯示 toast「語言將在下次啟動時套用」+「立即重啟」按鈕 - 「立即重啟」呼叫 Wails Go 端重啟 App - macOS 原生 menu bar 文字維持**首次啟動時**的 locale **M2(完整版,即時切換)**: - 切換後即時生效(不需重啟) - 所有 UI 文字立即更新(`i18next.changeLanguage()` + React context re-render) - macOS 原生 menu bar 需動態重建(Wails v2 `menu.Update()`) - 正在顯示中的 toast/modal/error 文案也要 reload - 寫入 config.json ## 10.8 原生 menu / OS 通知的 i18n > 第三輪決策 Q-A 已砍除 tray,本節不再涵蓋 tray menu。 | 項目 | 處理方式 | |------|---------| | macOS 原生 menu bar | Wails 啟動時讀取 locale,用對應字串建立 menu;語言切換後**需要重建 menu**(Wails v2 支援 dynamic menu update) | | OS 通知 | 每次發送時以當前 locale 字串構造 | | 錯誤對話框 | 同上 | ## 10.9 未翻譯的 fallback - 某個 key 在 `en` 缺失 → 顯示 `zh-TW` 版本(反之亦然) - 兩邊都缺 → 顯示 key 本身(開發時容易發現) - 生產版本 build 時執行 lint:所有頁面使用到的 key 必須在兩個 locale 都存在 ## 10.10 文案撰寫原則(繁中) - 台灣用語:「影片」不用「視頻」、「軟體」不用「軟件」、「程式」不用「程序」 - 語氣:友善但專業(技術工具,不需要太可愛) - 避免機翻語感:「載入失敗,請再試一次」> 「載入失敗了。請再次嘗試」 - 動詞在前:「儲存變更」> 「將變更儲存」 - 標題用名詞片語:「模型管理」> 「管理你的模型」 - 按鈕用動詞:「上傳」> 「上傳按鈕」 ## 10.11 文案撰寫原則(English) - Sentence case:`Upload model`(非 Title Case `Upload Model`) - 動詞優先:`Connect device`(主 CTA) - 簡潔:`Skip`(非 `Click here to skip`) - 避免縮寫:`Settings`(非 `Pref.`)