Developer tools
Over-the-air delivery
Publish the verified strings of a project as a bundle and let the running app fetch them, so a fixed translation reaches users without a release.
What you get
Verified text on devices, no release in between.
Five checks on every save
Placeholders, length, terminology, consistency and missing translations are flagged on the row they concern, not in production.
Every plural form a language has
Each locale gets exactly the CLDR categories it uses, Arabic six and Japanese one, written in the format's own plural shape.
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 APIOne catalog, every platform
The iOS app, the Android app and the web app share one project. Tag the keys only one of them uses and pull that subset alone.
Set it up
From nothing to every language.
Step 1: Create a distribution and publish
Under Delivery in the project, one distribution per platform. Publishing snapshots the verified strings; unverified text never ships.
Step 2: Mint a device key and use an SDK
A key is
dk_plus 64 hex characters, read-only, bound to one distribution and one SDK, and revoked in one click. It grants a read of verified strings and nothing else, so it may sit in the app binary; a CLI token can push and must never ship. The SDKs fetch static files under the key's URL and revalidate with an ETag. An extra iOS string table has its own path.shellcurl -sS "https://anylocale.com/ota/v1/<distribution key>/manifest.json" curl -sS "https://anylocale.com/ota/v1/<distribution key>/de.json" curl -sS "https://anylocale.com/ota/v1/<distribution key>/Settings/de.json"Step 3: Or fetch the whole bundle from a server
A bearer token with the read scope, the distribution id, and the etag from the last fetch. Unchanged content answers 304 with no body.
shellcurl -sS "https://anylocale.com/api/loc/distributions/<id>" \ -H "Authorization: Bearer $ANYLOCALE_TOKEN" \ -H 'If-None-Match: W/"<etag from last time>"'Step 4: Apply it on the next launch
The bundle is a map of locale to key to string. Keep the last good one on disk, never block app start on the fetch, and fall back to the strings compiled into the app for anything missing.
templatesholds keys with several counted variables; a client that does not render them ignores the map.response{ "version": 7, "etag": "W/\"3f0c1c5f…\"", "strings": { "de": { "paywall.subscribe_cta": "Jetzt abonnieren", "cart.items_one": "1 Artikel", "cart.items_other": "%d Artikel" }, "en": { "paywall.subscribe_cta": "Subscribe now", "cart.items_one": "1 item", "cart.items_other": "%d items" } }, "templates": {} }on launchetag = load_from_disk() # empty on first launch resp = GET /api/loc/distributions/<id> If-None-Match: etag 304 -> use the cached bundle 200 -> persist resp.strings and resp.etag, use them else -> keep the last good bundle, retry next launch
Good to know
- Republishing unchanged content creates no new version and keeps the etag, so a poll on every launch costs one 304.
- The device files carry plurals in each SDK's own shape and placeholders in each platform's own syntax; the bundle for servers ships plural forms as key_category entries.
- Keys with several named variables are not part of the device files; the app keeps its compiled string for them.
Questions
- Which strings ship?
- Verified ones only. A draft, an AI proposal or a string still in review is left out, and devices keep the last published wording for that key until the new one is verified.
- How often should the app fetch?
- On every launch is fine. Unchanged content answers 304 with no body, the SDKs revalidate with an ETag, and republishing unchanged content keeps the etag.
- What if a key is missing from the bundle?
- The app falls back to the string compiled into it. Keys with several named variables are never in the device files, and the compiled string covers those too.
- Can a key be revoked?
- Yes, in one click under Delivery. A distribution key is read-only, bound to one distribution and one SDK, and stops answering the moment it is revoked.
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.