Imported from autobrr/qui (
web/src/i18n/AGENTS.md). Install upstream withnpx skills add autobrr/qui --skill i18n. Copyright stays with the author.
AGENTS.md
Locale and translation rules for work under web/src/i18n/.
Layout
11 locales live under web/src/i18n/locales/<lang>/, each with 10 namespaces:
common, auth, settings, torrents, dashboard, crossseed, rss, search, instances, automations
English is fallback/eager-loaded. Other languages are lazy-loaded by initI18n() / changeLanguage() through import.meta.glob in web/src/i18n/index.ts. Supported today: en, zh-CN, zh-TW, fr, de, cs, it, ko, uk, pt-BR, ca.
Before you add a language, follow docs/agents/adding-a-language.md.
Translation Rules
- Read English namespace JSON and relevant UI first; translate in product context.
- Preserve placeholders, HTML tags, keys, examples, paths, URLs, commands, and technical notation unless the checker allows an exception.
- Byte and speed units and their decimal separator are the exception: they are localized, so render them through
web/src/lib/unit-format.tsand never hardcodeKiB,MiB/sorMbps. - In a
<Trans components={{…}}>string, give each tag a name that is not an HTML void element, for example<docs>ininstances.json. react-i18next readslink,img,br,input,meta, andhras self-closing, so the component does not wrap the inner text. - Keep a glossary for product names and torrent/domain terms.
- Plurals use the i18next v4 CLDR suffixes:
- English needs
_oneand_other. - Chinese and Korean take
_otheralone. csneeds_one,_fewand_other._manyis optional, because Czech uses it only for decimals and no count reaches one: item counts are whole numbers, and relative-time counts are floored inweb/src/lib/dateTimeUtils.ts.ukneeds_one,_few,_manyand_other.
- English needs
- A locale that omits a category it needs shows the English string at those counts. i18next resolves a missing category against
fallbackLng, never against another category in the same language. The gap therefore looks like a working translation. - An unsuffixed base key beside the suffixed ones answers every category the locale omits, with one string. Use it only for text that does not change with the count. The base key also hides a missing form from
pnpm check:i18n, socsorukcan show the wrong form, for example "2 trackerů". A base key must exist in English and in every locale, or the missing-keys and extra-keys checks reject it. - Never add the pre-v4
_pluralsuffix. i18next does not resolve it in any locale. pnpm check:i18nenforces these rules.check-legacy-plural-keys.mjsrejects_pluralin every locale, includingen.web/src/i18n/plurals.test.tsasks i18next whether each locale can resolve every plural base at nine counts, and fails on the ones it cannot, since the app serves English for those.- Product/ecosystem terms often stay English where clearer:
qBittorrent,Prowlarr,DHT,PEX. - Chinese text should prefer full-width
,。:;!?; half-width is fine inside URLs, IPs, paths, and technical notation.
