Skip to content

Optional analytics, session recording and advertising stay off unless you accept. You can reject them and use Transglot. Change your choice anytime in Cookie preferences. Cookie Policy

for teams that merge every day

Continuous localization: every language, on every merge.

Continuous localization translates new and changed strings as your code changes, instead of in a separate phase before each release. Every language stays ready to ship with the code that needed it.

A simulation of the two ways of working, not a measurement. Press Merge a change and read the column on the right: it is what that language's users see.
acme / web
mainAdd a gift cardcheckout.gift_card
frAjouter une carte cadeautranslated
deGeschenkkarte hinzufügentranslated
jaギフトカードを追加translated
arأضف بطاقة هديةtranslated
pt-BRAdicionar vale-presentetranslated
Languages you could release now5 of 5
Strings behind mainnone
the short answer

What is continuous localization?

Continuous localization is a way of working in which new and changed strings go to translation automatically as soon as they change, and the translated text comes back into the product without anyone scheduling it.

There is no translation phase, because translation never stops. A developer merges a string, the translations follow in the same flow as the code, and a release is not waiting on anyone's file.

It is the localization half of continuous delivery. A team that merges every day and hands off translation every few weeks has languages behind its code for most of every month. Continuous localization shrinks that gap to the length of one run.

It does not mean machine output goes live unread. You decide which strings need a person, and a release can carry only what has been reviewed.

continuous vs traditional localization

The difference is when translation happens, not who does it.

Translators, reviewers and glossaries exist in both columns. What moves is the moment the work starts and the size of each piece.
Side by side
When translation happens
In a phase before each release
What starts it
Someone exports a file
The size of each piece
Weeks of strings at once
What a release waits for
The file to come back
A late copy change
Another round trip
What the translator works from
A spreadsheet of strings
Languages at launch
Staggered, one wave after another
one string, start to finish

How continuous localization works

Follow one new string through the loop. Each stop shows what you would actually see.

your terminal, or your CI log
+ "checkout.gift_card": "Add a {brand} gift card"
$ git push origin main
$ transglot push --wait
push locales/en.json (en, json_nested)
Batch: #4182
$ transglot pull
written locales/fr.json
written locales/ja.json
checkout.gift_card
sourceAdd a {brand} gift card
frAjouter une carte cadeau {brand}Glossa draft
de{brand}-Geschenkkarte hinzufügenfrom memory, 0 words
ja{brand} ギフトカードを追加Glossa draft
arأضف بطاقة هدية {brand}Glossa draft
the four gates, one run
Placeholders1 repaired
Plural formspass
Glossary termspass
Lengthpass
ja · placeholder lost, repaired once, checked againギフトカードを追加{brand} ギフトカードを追加
cart.save
source changedSave Save draft
frEnregistrerreviewed by a person: kept, reported to youSuggested: Enregistrer le brouillon
deEntwurf speichernmachine row: translated again
pull requestupdated in place
Update translationstransglot/sync → mainopen, one per repository
locales/fr.json+3 −1
locales/de.json+3 −1
locales/ja.json+3 −1
or, on a pull request on GitHub, comment/translate

The change reaches Transglot through the CLI, the GitHub Action or the app on your Git host. Source files are parsed in one of 20 native formats, and each string is compared with what the project already holds. Only new and changed strings go on.

An exact match from translation memory fills the row and costs no words. Whatever is left goes to Glossa with your glossary, your style guide and the context of that key.

Placeholders, plural forms, glossary terms and length are checked on every row of every run. A broken placeholder, a missing plural form or a forbidden glossary term is repaired once and checked again, and if it fails a second time it is refused, not shipped. A row that only overruns its length is written, and from the Team plan auto-approve or a QA run flags it for review.

A run never writes over a row a person has edited or reviewed. If its source changes later, the text stays, the run counts the row and tells you, and from the Team plan a suggested update waits beside it for someone to accept.

The Git apps commit locale files to one sync branch and keep one pull request up to date. On GitHub, comment /translate on a pull request and the files land on that pull request's own branch. Or publish to the CDN, and the running product reads the change with no release at all.

where teams get burned

Six ways continuous localization goes wrong, and what stops each one

A run overwrites a person's work

Every writer checks the row's state first: a run, a memory match and a push. A row a person edited or reviewed stands, and the run reports it.

fr, reviewed, source just changed

kept, counted, reported

A broken string reaches production

Every token that went in has to come back out. On an ICU project, a message that would throw at render time stays out of the pull, the connector and the CDN bundle, and the run names it.

{count, plural, one {# article}

left out of the file, named in the run

The repository fills up with bot pull requests

One sync branch and one pull request per repository. Two quick pushes converge on it instead of opening a second one.

#812 #815 #819 #823 l10n update

#812 transglot/sync, updated in place

A source edit leaves old translations behind

Every target row records the source it was written against, so a changed string is known to be out of date in every language at once, and only that key runs again.

Save became Save draft. fr, de, ja still say Save

fr, de, ja run again on that one key

Every run bills the whole project again

A run is sized from what changed. An unchanged string is not sent, an exact memory match costs no words, and a row a person owns is refused before anything is spent.

file holds 48,000 words

this run: 60 words

A half-finished pull wipes a locale file

If the server reports no entries for a locale, the pull refuses to write over a file that has content, and exits 1 so the pipeline stops there.

pull: 0 entries for ja, file holds 1,204

refusing to overwrite locales/ja.json with an empty bundle

  • run 4182 fr: placeholder missing from the draft, repaired on retry
  • run 4182 de: 3 rows kept, a person owns them
  • run 4182 ja: 41 rows from memory, 0 words
  • run 4183 ar: plural form missing after retry, row refused
  • pull written locales/pt-BR.json
  • sync transglot/sync updated, pull request #812
measured against the two you are comparing

All three connect to your repository. What differs is what happens when you merge.

Read from each company's own pages on 5 November 2026. The price row comes from our comparison pages, linked below, which show the plan and the arithmetic. Prices and plans change, so check them before you decide.

Transglot
A new string is merged
Translated by default
The push starts the run. A project setting turns it off.
A translation fails a check
Repaired once, then refused
For a broken placeholder, plural form or forbidden term, on every row of every run. A length overrun is written. On an ICU project, a broken row stays out of the pull, the connectors and the CDN.
A person already edited the row
The run refuses to write it
So do a memory match and a push. If the source changes later, the run reports the row.
Pull requests on a busy repository
One branch, one pull request
Updated in place on each push.
What the plan counts
Words translated, once per language
Exact memory matches cost nothing. Storing a string costs nothing.
What pays for the AI
The plan's words
It is not billed separately.
The same job: 5,000 strings in 10 languages
$39 a month
Team, translation included
GitHub, GitLab, Bitbucket, Azure Repos, a CLI and an MCP server
All of them
The Git apps start on Team and cover the cloud editions.
use what you already run

Start it from wherever your strings live. Every door reaches the same pipeline.

The same memory, glossary, gates and review, whichever door a string came through.
.github/workflows/translations.yml
on:
push:
branches: [main]
jobs:
translations:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- uses: transglot/transglot-action@v1
with:
token: ${{ secrets.TRANSGLOT_TOKEN }}
what to do first

How to set up continuous localization

  1. Get strings out of the code

    Every user-facing string needs a stable key in a locale file. Transglot reads 20 formats, so keep the one you have.

  2. Connect the repository

    The init command finds your locale files, signs you in through the browser, uploads what you already have and runs the first translation.

  3. Run it on every merge

    Add the GitHub Action, call the CLI from any other CI, or install the app for GitHub, GitLab, Bitbucket or Azure Repos.

  4. Decide what needs a person

    Set min_state to reviewed on a pull rule and that file only carries strings a person has reviewed. Leave it off and drafts ship.

do the sums on your own numbers

What it costs to run on every merge: the words that changed.

A word is a source word, counted once per target language. A run is sized from what changed, so a merge that touches twelve words in five languages counts sixty, however large the project is.

25
40
6
20,000
Words a month26,000on these numbers · 25 merges a week, 40 words each, 6 languages

Fits on Starter: $19/mo, 300,000 words a month.

That is about 9% of the allowance.

First run, once120,000Your existing strings in every language. Translations you import are not translated again.

This counts translation only. Quality checks, brand voice drafts and repairs also count as words, and exact matches from memory cost nothing. The CLI and the GitHub Action start on Starter, and the apps for GitHub, GitLab, Bitbucket and Azure Repos start on Team.

what it will not do for you

Three things continuous localization does not solve

Strings still stuck in code

A pipeline can only translate what it can read. Hard-coded strings and sentences glued together from parts have to be fixed first, and they are the usual reason a rollout stalls.

Nobody owning the words

Automation moves strings. It does not decide what your product calls things. Someone has to own the glossary, or a language nobody reads drifts without anyone noticing.

Copy that needs judgement

Legal text, pricing and brand lines deserve a person. Send them to review and keep them out of the files that ship until someone signs off.

Continuous localization FAQ

The questions teams ask before they turn it on.

What is continuous localization?
A way of working in which new and changed strings go to translation automatically as they change, and translated text returns to the product without a scheduled handoff. It replaces the translation phase before a release with a small run after each change.
Traditional localization batches strings into a file, sends it out near a release and waits. Continuous localization moves each change as it happens, so the pieces are small, languages launch together, and a late copy change costs a re-run of one key rather than another round trip.
No. CI/CD builds, tests and releases code. Continuous localization keeps translations moving alongside it. They meet in the pipeline: the push that runs your tests can also send strings for translation and bring the files back.
No. The apps for GitHub, GitLab, Bitbucket and Azure Repos react to a push with nothing added to your pipeline, and content connectors react to changes in a CMS or store. The CLI and the GitHub Action are there if you want it inside your own workflow.
No. Drafts can ship, or a pull rule can carry only what a person has reviewed, file by file. Reviewers work in the editor with the glossary terms, memory matches and screenshots beside each row.
No. A run, a memory match and a push all check the row first, and a row a person has edited or reviewed stands. If its source changes later, the text stays, the run counts the row and reports it, and from the Team plan a suggested update is attached for someone to accept.
It tends to matter most on a small team, because nobody's job is running handoffs. If you ship in one language with no plan for a second, it can wait.
A run is sized before it starts. Free is a hard cap. A paid plan stops at its allowance unless you turn on metered overage, which stops at a spend cap you set. In CI, the CLI exits with code 3 when a run would pass the limit, so the pipeline can act on it.
Yes, on GitLab.com, Bitbucket Cloud and Azure DevOps Services. The apps do not cover self-managed GitLab or Bitbucket Data Center, but the CLI runs in any CI that has Node 22 and can reach the API.
Yes. Content connectors read from a CMS, a store or a help center, and the two-way ones write the reviewed language back. Some are import only, and each connector's page says which.
Yes. Publish a locale to the CDN and your product reads it at runtime through the runtime SDKs. The latest URL is cached for sixty seconds, each published version keeps its own URL, and the last twenty versions are kept.
The importer brings projects, keys and existing translations across from Lokalise, Phrase, Crowdin, Transifex, Weblate and POEditor. Imported translations count as human work, so no run overwrites them. It is free on any plan and runs once.