Formats
CSV
One locale as a spreadsheet: hand it to a translator who works in Excel or Numbers and import the result.
What you get
Everything the editor does, through the files you already ship.
AI drafts, a person verifies
Every language is drafted against your glossary and each key's length limit. A draft never ships until someone has verified it.
Five checks on every save
Placeholders, length, terminology, consistency and missing translations are flagged on the row they concern, not in production.
Everything is an HTTP call
Project tokens carry read, push and manage scopes, so a CI token that pushes files cannot delete keys.
The HTTP APIScriptable from the CLI
Push, pull and sync from a terminal, a build phase or a coding agent's shell, with a token in the environment.
The CLI
Set it up
From nothing to every language.
Step 1: The columns
One row per key, or one per plural category. The comment column carries the key's description so the translator sees the same context the editor shows. Only the value column is theirs to edit.
de.csvkey,variable,plural,value,comment cart.items,,one,1 Artikel,Items in the cart cart.items,,other,%d Artikel,Items in the cart onboarding.location_permission,,,"Standort, Wetter & Regen für %s erlauben",Explains why the app needs the location paywall.subscribe_cta,,,Jetzt abonnieren,Step 2: Install the CLI and log in
Homebrew or the one-line installer, then a token issued per project under Settings, Integrations. The read scope pulls; push writes source files and values; manage creates and deletes keys.
shellbrew install anylocale/tap/anylocale anylocale login --project my-appStep 3: Export one locale
The file opens in Excel, Numbers and Sheets as it is. Ask for it back as CSV with UTF-8 encoding, header row intact.
shellanylocale pull --project my-app --locale de --format csv --out de.csvStep 4: Import the edited file
The locale is named on the request. Rows are matched by key and plural category; a key the project does not have is reported, never created.
shellcurl -fsS -X POST "https://anylocale.com/api/loc/push?project=my-app&locale=de&format=csv" \ -H "Authorization: Bearer $ANYLOCALE_TOKEN" \ --data-binary @de.csv
Good to know
- A cell starting with =, +, -, @, a tab or a carriage return would open as a formula, so it is prefixed with an apostrophe on export and unprefixed on import. Translators should leave that apostrophe alone.
- Values written through a push are marked translated, not verified; verification stays a human step in the app.
Questions
- Does an import mark the strings verified?
- No. Values written through a push are marked translated, and verification stays a human step in the app, where the five checks have run on each row.
- Can one spreadsheet hold every locale?
- No, one file per locale. That is what keeps a translator's file to the one language they work in, and an import from reaching a locale it was not meant for.
- Which columns does the export have?
- key, variable, plural, value and comment. The plural column carries the CLDR category on a plural's rows and is empty otherwise; the variable column is used only by keys with several counted variables.
- Which other formats can the same project be pulled in?
- .xcstrings, .strings with .stringsdict, strings.xml, JSON, next-intl messages and CSV. A project is not tied to the format it was pushed in, which is how an iOS app and an Android app share one catalog..xcstrings.stringsstrings.xmlJSONnext-intlCSV
Start with the file your app already ships.
After checkout, import one strings file and read the first drafts within minutes.
Nothing to connect and nothing to install. The CLI is optional.