Community translation files for Cider
No fork, no PR, no command line. Fill in a short form; a maintainer reviews and the bot does the rest.
This repository holds every locale Cider ships, on desktop and on Android. The English source (locales/en-US.yml) is generated automatically from the two codebases; you can read it but please don't edit it here. Every other locale is fair game.
Three things keep this repo healthy:
- The apps mirror their English here. Whenever Cider's desktop code (Citadel) or Cider for Android adds or changes a translatable string, its sync workflow updates its own keys in
en-US.yml(see Two apps, one file). - AI fills new strings. When
en-US.ymlchanges,.github/workflows/ai-fill.ymlruns Anthropic Claude (specifically Haiku 5.5, model idclaude-haiku-5-5) against the delta, one job per language, and commits each language as soon as it's done. The shared system prompt (rules and glossary) is sent with Anthropic prompt caching so later batches in the same job read that prefix from cache. Per-batch English strings are not cached. Each request logscache_creation_input_tokensandcache_read_input_tokens. - Humans correct what the AI gets wrong. Open a translation issue with the corrections, a maintainer labels it
approved, and a bot applies the change with full credit attached.
| File / directory | What it is |
|---|---|
locales/en-US.yml |
English source. Read-only here; edits get overwritten by the app syncs. |
locales/<code>.yml |
One file per target language. This is where translations live. |
locales/languages.yml |
Supported languages with display names. Citadel's snapshot is merged on sync; languages registered here are kept. |
scripts/i18n-translate.mjs |
The AI translator (Anthropic Claude Haiku 5.5, with prompt caching on the shared rules prefix). Runs in CI; you generally won't run it locally. Needs ANTHROPIC_API_KEY. |
.github/ISSUE_TEMPLATE/translation.yml |
The contribution form. |
i18n/owners.yml |
Which app owns which keys of en-US.yml. |
i18n/fill-state/<code>.yml |
Bookkeeping for the AI fill: which English each translation was made from. Written by the bots. |
i18n/consumers/<app>.yml |
Desktop keys the Android app also reads. Written by the Android sync. |
scripts/i18n-sync-source.mjs |
What each app's sync runs to update its own keys in en-US.yml. |
Translation files are YAML. Each key maps to either a scalar (AI-translated) or a map (community-contributed, with credit).
# Scalar = AI-translated. May be re-translated automatically if the English source changes.
action.apply: Aplicar
# Map = community-contributed. The bot writes this shape after a maintainer approves an issue.
action.back:
value: Atrás
source: human
by: '@yourhandle'
issue: 1234The runtime reads value (or the scalar). The extra fields are credit metadata.
When an AI re-translation overwrites a human entry (because the English source changed), the map is preserved with source: ai and a superseded_at date, so credit isn't lost. The original contributor is notified on the issue thread.
Cider for desktop and Cider for Android share these locale files. Keys starting with mobile. belong to the Android app; every other key belongs to desktop (i18n/owners.yml). Each app's sync replaces only its own keys in en-US.yml, so neither can delete the other's strings, and they can land in either order.
Android's strings use ICU MessageFormat, which handles plurals properly:
mobile.library.songCount: "{count, plural, one {# song} other {# songs}}"
mobile.playlist.addedTo: Added to {playlist}When translating them, keep every {argument} name as it is, translate only the text inside each plural branch, and add the plural forms your language needs (few, many). A straight apostrophe right before { hides the placeholder (l'{playlist} prints {playlist}), so use the typographic one (l’{playlist}). The bot checks all of this.
An Android string with the same English as a desktop string reuses the desktop translation, so a correction to one helps both.
See CONTRIBUTING.md. The short version: open an issue, don't open a PR, the bot does PRs so attribution stays consistent.
Every entry below came from a community member through a translation issue. Thank you! Contributors are also credited as the git author of the commit that applied their work, so this same crew shows up in the contributors graph.
| Translator | Languages | Entries |
|---|---|---|
| @JackW25 | Icelandic | 3185 |
| @Tesutarin | Chinese (Simplified) | 2320 |
| @jay900604 | Chinese (Hong Kong), Chinese (Simplified), Chinese (Traditional) | 1701 |
| @mpratsaki | Greek | 1050 |
| @kinlay0 | Russian | 647 |
| @szymin22 | Polish | 111 |
| @Vudgekek | Croatian | 103 |
| @nekocats | Estonian | 93 |
| @lumaa-dev | French | 68 |
| @MP-K | Korean | 27 |
| @ramuuflor | Japanese | 22 |
| @jamiw1 | Dutch | 18 |
| @sh-ayu | Japanese | 18 |
| @itsmeares | Turkish | 16 |
| @emirasaf | Turkish | 11 |
| @felipecadal | Portuguese (Brazil) | 1 |
| @UnoPanduo | Dutch | 1 |
| @yako0755 | Japanese | 1 |
Translation content is contributed under the terms outlined in CONTRIBUTING.md. Cider itself is closed-source; this repository exists to keep translation work in the open.