Questions

Automating translations

We get these questions from people evaluating tools and from people who have decided to build it themselves.

Working on this and want a second opinion on the setup? Get in touch. Happy to help even if you end up building it yourself.

Can translations be triggered automatically when code is committed?

The usual shape is a CI job that runs on pull requests. It compares the branch against the base branch, finds locale keys that are new or changed, translates those and commits the result back to the same pull request. Nothing runs on merge and nothing re-translates the whole catalog every time.

The part teams usually get wrong is the diff. Most CI systems do a shallow clone by default, which leaves nothing to compare against, so the job either translates everything or nothing.

Localhero's GitHub Action runs this loop for you, with your glossary and style guide applied on every run. Translations arrive on the pull request already in your product's voice, ready for someone to review.

How to automate i18n translations with GitHub Actions

How do we translate only the keys that changed in a pull request?

Localhero's GitHub Action diffs the pull request branch against its base, finds keys that were added or whose source text changed, translates only those and commits them to the same PR. It works the same way for Rails YAML, JSON and gettext .po files. Translations that were already reviewed are left alone.

If you build it yourself, compare parsed keys rather than raw diff lines. Otherwise reformatting or reordering a file triggers a retranslation. Track changed source values as well as new keys: when a button changes from "Pay now" to "Place order", every language needs the new text. Localhero handles all of this for you, with your glossary and style guide applied to every key it translates.

Translate JSON and YAML locale files in CI

Does Localhero work outside GitHub, on GitLab or Jenkins?

Yes, through the Localhero CLI. The prebuilt GitHub Action is the quickest setup. Anywhere else that runs a shell, you run the CLI with a --changed-only flag, which does the same base-branch diff. You need Node 18 or later, an API key in the runner environment and a clone that actually contains the base branch.

The one thing that does not carry over is branch detection. A command that reads GitHub's own environment variables cannot identify the branch on other runners, so use the explicit translate command instead.

Running translations in CI/CD pipelines

How do we set this up in a monorepo with several apps?

Give each app its own Localhero project, with its own localhero.json in the app's folder. One workflow at the repo root runs a matrix job per app using the Action's working-directory input. Each app then translates its own files on the same pull request.

Terms every app shares, like your product name, go in an organization-level glossary. One thing does not work yet: Export to GitHub from the dashboard assumes localhero.json sits at the repo root.

Setting up Localhero in a monorepo

Should translations go in the same PR as the code, or a separate one?

Same PR, in most cases. The argument for a separate PR is that it keeps the code diff clean, but that assumes reviewers have somewhere else to check the copy. If they do not, splitting means the strings ship unreviewed.

The deciding factor is whether a reviewer has a surface outside the code diff, not how large the diff gets. Localhero gives them one: a review page per pull request where a PM or native speaker reads the translations as copy, not as YAML. Their edits land back on the same PR.

Should translations go in the same PR or a separate one?

Can an AI coding agent just do this instead?

For a one-off pass, yes, it will look fine. What degrades is consistency across runs: the same term rendered three different ways in three files and silent omissions when a batch is large. Agents also tend to forget the step entirely, which is how untranslated strings reach production.

An agent is good at writing the source string and bad at guaranteeing the same decision twice. So it is worth making translation a deterministic build step and letting the agent do what it is actually good at. That build step is what Localhero is: the same glossary, style guide and translation memory on every run, plus a validation pass that checks placeholders and structure on every translation. If you work in Claude Code or Cursor, an agent skill can give your assistant your glossary and naming conventions so the strings it writes match your existing patterns.

Your coding agent should handle translations too

Which file formats does Localhero support?

YAML for Rails, JSON for React and Vue (i18next, next-intl, react-intl, LinguiJS, vue-i18n) and gettext .po for Django, Phoenix and Lingui.

The .po format behaves differently from key-based formats. The source text is the key, so editing copy orphans its translations and how many plural forms a message needs depends on the target language. Lingui's .po is different again, storing ICU MessageFormat inline rather than using gettext's indexed plural slots.

Auto-translate gettext .po files in CI

How do you keep terminology and tone consistent?

Two mechanisms. A glossary pins terms that must always translate a particular way, or never translate at all. A style guide captures tone, formality and how you address the user, which matters more in languages with a formal and informal register than it does in English. Without them the output reads like a translation instead of like your product.

In Localhero both are part of every project and apply to every translation. You don't have to write them from scratch: Localhero can draft the style guide and pull glossary terms from the translations you already have. On top of that, every correction a reviewer makes goes into the project's translation memory. Fix a term once and later translations follow it, PR after PR.

Setting up style guides and glossaries

How does a human review Localhero's translations without touching code?

Reviewers edit in a dashboard and the edits sync back to the originating pull request as a commit. Someone who does not use git, a PM or a native-speaker colleague, can correct copy without a checkout.

You can also turn off automatic translation per language, which teams do when they have a native speaker for one market and want AI for the rest.

How the review workflow works

We ship weekly. How do we automate localization without slowing releases?

Take translation off the release path entirely. If it runs per pull request rather than per release, there is no batch to prepare and nothing to wait for at the end: the strings for a feature are translated by the time that feature merges.

The pattern that holds up at a weekly cadence is the same one you already use for tests. Tests run, translations generate, code ships. What breaks cadence is treating localization as a phase, collecting strings into a handoff and waiting for them to come back, because that queue only ever grows with release frequency.

Reviewing is the part worth designing for. If a native speaker has to read every string before merge, that becomes the new bottleneck, so most teams reviewing at this cadence check the high-traffic surfaces and let the rest ship, correcting later if needed.

How to automate your translation workflow

How do we set up automated translation workflows for product releases?

Attach translation to the pull request, not to the release. Connect the repo, point the tool at your locale files and run it as a CI job on every PR. New and changed keys come back translated on that branch before it merges. By the time you cut a release, every feature in it already carries its languages.

With Localhero that is a GitHub Action plus a config file in the repo. It diffs the PR against its base, translates only what changed with your glossary and style guide applied and commits the result to the same PR. Release day needs no translation step at all. Teams that want a native speaker to look at the copy do it on the review page while the PR is open.

How to automate your translation workflow

Do we really need a TMS?

For most product teams, no. A TMS adds a second system of record: strings live both in the repo and in the platform. Someone has to keep them in sync. If your strings already live in git and the bottleneck is that nobody remembers to translate them, translating in CI is the smaller fix.

Localhero is a lightweight TMS that lives in your pull requests. You get the parts that matter for quality, like a glossary, a style guide, translation memory and a review page, without moving your strings out of the repo. Translations arrive as commits on the PR.

A full TMS still earns its place if you employ translators who need a web workbench and vendor management.

SaaS localization without a TMS

What does automating this actually cost?

It depends on volume, but usually less than the coordination it replaces. The thing to compare is not per-word rates against an agency. It is the total of what you spend now, including the engineering time spent shepherding strings between systems.

With Localhero there is nothing to build or maintain. You can try it on your own repo free for 30 days, no credit card needed.

What SaaS localization actually costs

How do you check translation quality at scale?

You cannot read everything once you are past a few languages. What works is sampling plus targeted checks: verify that glossary terms are honoured, that placeholders and ICU structure survived and that plural categories match the target language rather than the source. Then have a human read the high-traffic surfaces.

Localhero runs those checks on every translation: variables and placeholders, HTML tags and JSON structure. A quality check on the pull request flags strings worth a second look. Reviewers spend their time on the copy that matters instead of hunting for broken variables.

How to evaluate AI translation quality

How do small teams do this without a localization person?

By making the automated path the default and reserving human attention for the copy that matters. Most teams that struggle here are trying to run a manual process that nobody is assigned to.

That is the team Localhero is built for: a product team of a few developers shipping in several languages, with nobody whose job is localization. Translations happen on each pull request in your brand voice. Anyone on the team can fix a word on the review page without touching git.

How to localize your SaaS with a small team

Need help setting up translation management for your SaaS startup?

The setup that holds up for a small SaaS team: strings stay in the repo, translation runs on every pull request and review happens on a page anyone can use. No separate platform to keep in sync, nobody assigned to shepherd strings around. You add a glossary for product terms and a short style guide for tone. Everything else is automatic.

Localhero is built for exactly this team. Install the GitHub Action, add your locale files and the first PR comes back translated in your product's voice. The trial runs on your own repo for 30 days. If you want a second opinion on your setup before committing to anything, email hi@localhero.ai and we will look at it with you, even if you end up building it yourself.

How to localize your SaaS with a small team

Which approach fits our stack?

Broadly three: do it yourself with scripts, use a code-native tool that runs in CI, or adopt a full TMS. Which fits depends on how often you ship, whether you employ translators and whether your strings already live in the repo.

For a product team that ships often and keeps its strings in the repo, the code-native option is usually the fit. That is what Localhero is: translation on every pull request with your glossary and style guide, plus a review page for people who don't use git. No scripts to maintain.

DIY vs code-native vs TMS

How do I automate translation of strings and docs stored in GitHub repos?

For UI strings, Localhero's GitHub Action handles it on every pull request: it diffs the branch for new or changed keys, translates those in your brand voice and commits them back to the branch. That covers YAML, JSON and gettext .po files that live in the repo alongside the code.

Docs are a different problem and worth separating. Markdown is not key-value, so a diff has to work at paragraph or section level or a typo fix retranslates the whole page. Localhero handles the string files today; for Markdown docs most teams still run a separate script or translate on release.

Translate JSON and YAML files in CI

How do we sync translations with CI/CD pipelines?

Localhero runs as a GitHub Action on every pull request. New or changed keys get translated inside the PR that added them. Edits someone makes in the dashboard come back as a commit on that same PR, or as a pull request of their own for strings already on main. The repo stays the source of truth the whole way.

Whatever tool you use, there are two directions to keep in sync. Code to translations is the easy one: CI sees new keys and fills them. Translations to code is the one that breaks, since an edit made in a web UI has to get back into the repo without someone copying files by hand. Anything that writes straight to your default branch will eventually disagree with the code. Nobody notices until a customer reads the wrong string.

How translations and review edits land in the pull request

Can Phrase, Crowdin or Lokalise sync translations with our GitHub CI/CD pipeline?

Yes. All three have first-party GitHub integrations. Phrase Strings imports locale files from your repo and exports translations back as a new pull request, by default on a phrase-translations branch. Crowdin's GitHub Action opens a pull request with the translated files. Lokalise ships push and pull actions. In each case the translation happens on the platform, where translators and reviewers work.

The difference is where the translations land. A TMS integration brings them back on a separate branch or pull request once they have been through the platform, which suits a localization team that works in the TMS every day. Smaller product teams that ship several times a week usually want something else: a feature and its translations in the same pull request. Localhero translates inside the pull request that added the keys, with your glossary and style guide applied. The feature gets reviewed, merged and released with its translations already in it. Nothing is left to sync afterwards and no release is blocked waiting for translations.

The GitHub Actions for i18n translation, compared

Which translation tool works with GitHub Actions, React and a design handoff?

Split the question by where the strings live. If they are JSON files in the repo, Localhero translates them on each pull request in your product's voice. The team reviews the copy on a review page instead of in the diff. If your designers need visual context on every string before it ships, that is what a traditional TMS with a Figma integration is built for.

Most teams do not need both. The honest test is whether anyone outside engineering actually reviews copy before release. If not, the design handoff is a requirement on paper rather than a workflow, and paying for it slows the release without improving the result.

How to pick a translation setup for your stack

Question not answered here? Email hi@localhero.ai. We would rather point you at the right setup, including one we do not sell, than have you pick badly.

Try it on one pull request

Point Localhero at your locale files and open a PR. New strings come back translated, with your glossary and tone, ready to review before merge.