AI-translate your i18next files in CI with Locize. On every push it extracts your changed reference keys, syncs them to Locize, triggers AI auto-translation, and pulls the results back — delivered over the Locize CDN so translation fixes go live without redeploying your app.
It is a thin wrapper around i18next-cli localize --ci. The CI flow is detect → extract → sync --auto-translate → download. Instrumentation (rewriting your source to add t() calls) is skipped in CI — this action never touches your source files.
- ✅ Extracts new/changed keys from your code and syncs them to Locize.
- ✅ Triggers AI/MT auto-translation of the new keys (auto-translation is on by default for new Locize projects).
- ✅ Downloads the translations into your locale files.
- ❌ Does not rewrite your source code (no instrumentation in CI).
- ❌ Does not commit or open a PR — pair it with a commit/PR step (see Committing the results). Keeping this action single-purpose lets you compose it with whatever git workflow you already use.
A brand-new free Locize project can auto-translate a limited starter amount out of the box — enough to see it work end to end on a small app. For continuous translation you either:
- subscribe to a paid plan (which also unlocks the trust layer below), or
- bring your own AI/MT key (OpenAI, Gemini, Mistral, DeepL, Lara) on a plan that supports it.
This action does not give you unlimited free translation, and it doesn't pretend to. What it gives you for free is a working CI pipeline + the managed delivery layer, with a clear upgrade path when translation volume and review actually matter.
- Create a Locize project — sign up at locize.app/register. Project creation is a manual step; there is no headless "create project" in CI.
- Have an
i18next.config.{ts,js}in your repo. If you don't yet, runnpx i18next-cli init(or the full localnpx i18next-cli localize) once and commit the config. Your target languages from that config are created automatically on the first sync. - Add two repository secrets:
LOCIZE_PROJECTID— your Locize project idLOCIZE_API_KEY— any write-capable Locize API key
name: Translate
on:
push:
branches: [main]
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: locize/translate@v1
with:
project-id: ${{ secrets.LOCIZE_PROJECTID }}
api-key: ${{ secrets.LOCIZE_API_KEY }}This action writes translated files but leaves git to you. Pair it with a commit (or PR) step:
- uses: locize/translate@v1
with:
project-id: ${{ secrets.LOCIZE_PROJECTID }}
api-key: ${{ secrets.LOCIZE_API_KEY }}
# Option A — commit the updated translations back to the branch
- uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: 'chore(i18n): update translations'
# Option B — open a pull request instead
# - uses: peter-evans/create-pull-request@v7
# with:
# commit-message: 'chore(i18n): update translations'
# title: 'Update translations'
# branch: i18n/update-translationsHeads-up — AI translation is asynchronous. Auto-translation runs on the locize side after the sync. With
--cithe action does a single download and does not wait, so a freshly added key may still be empty in the same run; the next push (or run) picks it up. If you serve translations through i18next-locize-backend, the CDN delivers them live regardless of when you commit the files.
The action runs the full flow by default, but you can scope it to match how much of the pipeline your repo already owns:
command |
What runs | Use when |
|---|---|---|
localize (default) |
detect → extract → sync → auto-translate → download | Your code calls t() and you want the action to (re)extract keys, push them, translate, and pull results. Instrumentation is always skipped in CI, so already-instrumented code is fully supported — your source is never modified. |
sync |
sync → auto-translate → download | Your locale files are already extracted (committed in the repo, or produced by an earlier step). The action skips extraction entirely — no source parsing — and just reconciles the existing files with Locize. |
Already instrumented, only need extract + sync? That's the default — use the Quick start workflow as-is. In CI the instrument step is skipped, your keys are extracted, and they're synced to Locize.
Already instrumented and extracted, only need the sync? Set command: sync so extraction is skipped too:
- uses: locize/translate@v1
with:
command: sync
project-id: ${{ secrets.LOCIZE_PROJECTID }}
api-key: ${{ secrets.LOCIZE_API_KEY }}Free CI translators like lingo.dev's Action and ai-i18n are a good fit when you want translation to run entirely in your pipeline on your own LLM key. They are free at volume because you pay the LLM bill. Here's the honest difference:
| This action (locize) | lingo.dev Action / ai-i18n | |
|---|---|---|
| Free at volume | Free starter amount; then subscribe or bring your own key | Free at volume on your own LLM key |
| Who pays the translation bill | locize (starter) → you (subscription or your key) | You (your LLM key) |
| Managed CDN delivery | ✅ Update translations without redeploying | ❌ Commit-and-redeploy |
| i18next-native depth | ✅ Plurals/context/namespaces, 16+ formats | Varies |
| Trust layer | ✅ See below | ❌ Raw MT output |
If raw MT in your repo is all you need, those tools are fine — use them. The reason to come (or stay) here is the layer on top of the translation.
When translations stop being throwaway and start needing to be trusted, the paid layer is the product:
- Quality Estimation — confidence scores on AI translations, shown in the editor, so you know which strings to look at.
- Review workflow — route low-confidence AI translations to a human instead of accepting them blind.
- EU AI Act / review-provenance export — an auditor-shaped record of who reviewed what, when, and at what confidence.
"Free CI translation in → governed trust layer up" — that's the path this action puts you on.
| Input | Required | Default | Description |
|---|---|---|---|
project-id |
✅ | — | locize project id (use ${{ secrets.LOCIZE_PROJECTID }}). |
api-key |
✅ | — | Write-capable locize API key (use ${{ secrets.LOCIZE_API_KEY }}). |
command |
localize |
Flow to run: localize (full: extract → sync → translate → download) or sync (sync → translate → download, for already-extracted repos). See Choosing what runs. |
|
working-directory |
. |
Directory containing your i18next.config.{ts,js}. |
|
config |
— | Explicit config file path, overriding auto-detection. | |
cdn-type |
standard |
locize CDN endpoint: standard or pro. |
|
update-values |
false |
Also update existing translation values on locize, not only add new keys. | |
skip-translate |
false |
Sync keys but do not request AI auto-translation. | |
dry-run |
false |
Preview every step without writing or pushing anything. | |
cli-version |
1 |
i18next-cli major version/dist-tag to install. Defaults to 1 (all v1.x fixes, no breaking-major surprise); set to latest for the newest release. |
|
node-version |
24 |
Node.js version (i18next-cli requires >=22). |
- Idempotent and safe to re-run. Already-synced keys are not re-created; syncing never overwrites translations edited remotely unless you pass
update-values: true. - Reference-language driven. Auto-translation fires when the reference language gains keys; target languages are filled from it.
- Credentials. Provide
project-id/api-keyviawith:(as above) or via environment variables — bothLOCIZE_PROJECTIDandLOCIZE_PROJECT_ID(andLOCIZE_API_KEY/LOCIZE_APIKEY) are accepted. The api-key is masked in logs by GitHub Actions; never expose it in client-side code — the CDN only needs the project id.