多語系
SkyLab 提供 English、繁體中文與日本語。翻譯放在四個地方,規則到處一樣:每個 key 都要加到每種語言,而且逐句人工翻譯。
前端
- 使用 react-i18next。語系檔在
frontend/src/locales/{zh-TW,en,ja}/,每個命名空間一個 JSON(common、components、personal、resource、teaching、system、network、ai、login、services)。 - 檔案是扁平的、一行一個 key、CRLF 換行。它們不是
JSON.stringify的輸出;逐行編輯,改完用JSON.parse驗證。整檔重排的工具會產生大量雜訊 diff。 - 命名空間依頁面分類;key 以元件與元素命名(
UserGuide.monitoring.alerts.title)。 en與ja延遲載入;zh-TW隨應用程式打包,是後備語言。- 應用內的頁面導覽(
frontend/src/components/UserGuide/pageGuides/)引用UserGuide.*的 key;新頁面的導覽文案也要三種語言都有。 - 語言依瀏覽器選擇(側欄的「語言 / Language」,或初始化精靈與首次登入引導裡的語言選單),存在
localStorage(skylab.lang),並以Accept-Language送給後端。
後端
- API 訊息(錯誤、驗證、通知)走
app.core.i18n.t("<領域>.<key>", **params)。語系檔是backend/app/locales/<lang>/裡的檔案,扁平的key -> 樣板,用str.format佔位。同一語言的所有檔案會合併成一份目錄,所以 key 放在哪個檔只是把相關訊息歸在一起,不同檔案之間的 key 不可撞名。en或ja缺少的 key 會退回 zh-TW,再退回 key 本身。 - 請求的語言由
RequestContextMiddleware從Accept-Language解析並存在 context variable;t()在拋出錯誤時讀取,所以訊息在產生錯誤的地方翻譯,不是在呈現的地方。 - 背景寄出的郵件與稽核日誌刻意不翻譯:它們沒有請求語言。
桌面端
SkyLab Connect 的語系檔在 desktop-client/src/lang/,同樣三種語言、同樣的規則。
官網
site/ 的介紹網站每種語言一個語系檔 site/src/locales/{zh-TW,en,ja}.json,SEO 的標題與描述也在裡面。每種語言是各自預渲染的網址(/、/en/、/ja/),所以那裡的語言選單是在頁面之間切換,不記住選擇。三個檔案的 key 不一致時測試會失敗。詳見官網。
文件
本站的指南有 English 與繁體中文兩版(website/<page>.md 與 website/zh-TW/<page>.md)。指令、路徑、表格與標題結構保持一致,內文逐句翻譯。只有單一語言的頁面會在側欄標示。
不可妥協的規則
en與ja禁止機器翻譯、禁止腳本批次用正規表達式替換:讀懂語境再寫。審查者會比對三個檔案。- 不可漏掉任何語言的 key:react-i18next 會退回顯示 key 名稱,直接出現在介面上。
- 識別字、路徑、產品名稱與 API 路由不翻譯。
- 介面文字改了,導覽文案與對應的手冊頁要在同一次變更裡更新。