How to prevent untranslated UI from reaching production with GitHub

A practical, debt-aware way to add localization checks to pull requests — without blocking adoption on every existing hardcoded string.

JULY 22, 20262 min read← All articles

The naive localization gate is simple: scan the repository and fail if any untranslated string exists. It's also the fastest way to make a team disable the check.

Real codebases already have localization debt. A useful pull-request check answers a narrower question first: did this change make things worse? Answer that well and you can adopt the check today — and get stricter whenever you're ready.

Start with a differential check

A differential check compares your PR against its base and sorts findings into three buckets:

  • New — introduced by this change
  • Existing — inherited debt
  • Resolved — fixed by this change

Existing debt stays visible, but it isn't the author's problem on every unrelated PR. New strings are.

With Polyglot, the open GitHub Action runs this on any plan, from a workflow your repo owns:

- uses: actions/checkout@v4
  with:
    fetch-depth: 0
- uses: polyglot-i18n/polyglot-action@v1
  with:
    check-mode: differential

That's the whole setup. No API key required — the Action runs in guest mode.

Turn on blocking deliberately

Don't make an unfamiliar signal a required check on day one. A rollout that sticks looks like this:

  1. Run it informational for a week or two.
  2. Check for false positives and configuration gaps.
  3. Look at your baseline — that's your existing debt, counted.
  4. Agree on who owns new findings.
  5. Then make the check required in GitHub.

Nobody's merge gets blocked until you decide it should.

Let Polyglot open the translation PR

Polyglot Automation — in early access for Team and Scale — picks up where the check leaves off. When new strings land, it keeps your catalogs in sync, generates translations, and holds them for human review. Once someone approves, Polyglot verifies the change against a pristine base — your own checks have to pass on both — and opens a catalog-only pull request.

A few design decisions worth knowing before you install anything:

  • Two separate GitHub Apps. The Checks App can't write repository contents at all. The Publisher App — a separate, optional install — can only push verified catalog branches and open pull requests.
  • No long-lived secrets. The managed workflow authenticates with GitHub OIDC and gets a credential scoped to a single run.
  • Never straight to main. Translations arrive as a PR; your branch protections and code review still decide what merges.

Keep a human in the loop

Generated translations aren't approved changes. Review is on by default: someone sees the source string, the context, and the exact diff before anything ships. If verification fails on the candidate, the PR doesn't open.

That's the whole idea. The check stops regressions where they start, and translations ship the way the rest of your code does — as a pull request someone reviewed.

Add the open Action today. The rest is there when your team wants it.

Start in your terminal

Stop hunting for untranslated strings.

Install the CLI, run a scan, and see exactly what you're missing. Free, no account required.

$curl -fsSL https://getpolyglot.ai/install.sh | sh
How to prevent untranslated UI from reaching production with GitHub - Polyglot Blog | Polyglot