Skip to content

Internationalisation ​

SkyLab ships in English, 繁體中文 and 日本語. Four places carry translations, and the rule is the same everywhere: add every key to every language, and translate by hand.

Frontend ​

  • Library: react-i18next. Catalogs live in frontend/src/locales/{zh-TW,en,ja}/, one JSON file per namespace (common, components, personal, resource, teaching, system, network, ai, login, services).
  • Files are flat, one key per line, in CRLF. They are not the output of JSON.stringify; edit them line by line and validate with JSON.parse afterwards. Tools that reformat the whole file produce noisy diffs.
  • Namespaces follow the page areas; a key is named after the component and the element (UserGuide.monitoring.alerts.title).
  • en and ja are loaded lazily; zh-TW is the fallback bundled with the app.
  • The in-app guided tours (frontend/src/components/UserGuide/pageGuides/) reference keys under UserGuide.*; a new page needs its tour texts in all three languages too.
  • Language is chosen per browser (the "語言 / Language" item in the sidebar, or the picker in the setup wizard and the onboarding), stored in localStorage (skylab.lang) and sent to the backend as Accept-Language.

Backend ​

  • API messages (errors, validation, notifications) go through app.core.i18n.t("<area>.<key>", **params). Catalogs are the files in backend/app/locales/<lang>/, flat key -> template with str.format placeholders. All files of one language are merged into a single catalog, so the file a key lives in only groups related messages and keys must not collide across files. A key missing in en or ja falls back to zh-TW, then to the key itself.
  • The language of a request is resolved by RequestContextMiddleware from Accept-Language and kept in a context variable; t() reads it at raise time, so messages are translated where the error is created, not where it is rendered.
  • E-mails sent in the background and audit log entries are intentionally not translated: they have no request language.

Desktop client ​

SkyLab Connect keeps its catalogs in desktop-client/src/lang/; the same three languages, the same rule.

Public site ​

The introduction site in site/ has one catalog per language, site/src/locales/{zh-TW,en,ja}.json, including the SEO title and description. Each language is its own prerendered URL (/, /en/, /ja/), so the picker there links between pages instead of storing a choice. A test fails when the three files do not have the same keys. See Public site.

Documentation ​

Guides on this site exist in English and 繁體中文 (website/<page>.md and website/zh-TW/<page>.md). Commands, paths, tables and headings structure stay identical; prose is translated sentence by sentence. Pages that exist in one language only are marked in the sidebar.

Rules that are not negotiable ​

  • No machine translation, no batch regular-expression replacement for en and ja: read the sentence in context and write it. Reviewers compare the three files.
  • Never leave a key out of a language: react-i18next falls back to the key name, which ends up in the UI.
  • Do not translate identifiers, paths, product names or API routes.
  • When UI text changes, update the tour text and the matching manual page in the same change.

Released under the AGPL-3.0 License.