Documentation

Getting started

export SYNCLOCALE_API_KEY=sl_…      # from the dashboard
export SYNCLOCALE_PROJECT=…          # from the dashboard

synclocale extract                   # writes synclocale.manifest.json
synclocale push                      # sends it, reports what changed
synclocale status                    # how much is translated and reviewed

Commands

synclocale extract
Walks your project, finds every translation call with a literal key, and writes synclocale.manifest.json. Reads TypeScript, JavaScript, Go, Python, Ruby, PHP, Java, Kotlin, Swift and Dart, plus .strings, Android strings.xml and JSON catalogues. Never descends into node_modules or vendor directories.
synclocale push
Extracts fresh and sends the result. Reports exactly what changed: new, updated, archived. A push that changes nothing says so. Keys your code no longer references are archived, not deleted, and stop counting towards your plan.
synclocale status
Shows the key count and, per language, how much is translated and how much a human has reviewed. Changes nothing, so it is safe in a pre-commit hook.
synclocale pull
Writes every dictionary into your repository as sorted JSON. Use it to bake translations into a build, or to leave.

Monorepos

If one CI job only sees part of the project, pass --partial. Without it, a push archives every key the manifest does not contain — which, from a job that only built one app, would archive every other app’s strings.

Serving dictionaries at runtime

Publishing compiles a versioned snapshot and serves it with an ETag, so an unchanged dictionary costs a 304 rather than a download. Fetch it directly:

const messages = await fetch(
  'https://…/cdn/PROJECT_ID/es/common.json'
).then((r) => r.json())

A namespace with nothing published answers with an empty object rather than a 404, so your client falls back to its default locale instead of throwing.

What we will not do