BabelizeBabelize
CLI

Check Translations

QA your locale files from the terminal or CI: missing keys, lost placeholders, broken ICU and plural forms, glossary violations. Read-only, no network, no account.

babelize check compares every locale file in your project with the source locale and reports what would break or look wrong in the app. It reads files only: nothing is translated, nothing is sent anywhere, and no API key or account is needed. It runs the same checks as the MCP server's babelize_check tool and the validation babelize translate applies to fresh translations.

npx @babelize/cli check
  public/locales (source en, 42 keys)
    ✓ de       42/42 translated
    ✗ fr       41/42 translated · 2 errors

  error   public/locales/fr.json checkout.total [missing_key]
          Missing in this locale; the app falls back to the source text.
  error   public/locales/fr.json cart.items [placeholder_mismatch]
          Placeholders differ from the source: lost {count}.

  ✗ 2 errors, 0 warnings

What it checks

SeverityIssues
errorMissing keys, empty values, placeholders or tags lost or invented ({name}, {{count}}, %s, <link>; in ICU messages checked branch by branch), invalid ICU messages or changed arguments, missing plural forms the language needs (ICU and i18next _one/_other keys), pseudo-localized test text (⟦…⟧ from --provider pseudo), unreadable locale files, and locales with no file at all
warningValues identical to the source text (two or more words: looks untranslated), changed URLs, plural forms the language doesn't use, glossary violations
infoKeys that exist only in the target locale (stale or renamed), single words identical to the source (fine for names and codes). Shown with --verbose.

A translation may turn a count placeholder into an ICU plural (You have {itemCount} items → {itemCount, plural, one {…} other {…}}), as babelize translate does for languages that need it. A plural over a placeholder that isn't a count, such as {name}, is an error.

Locale files are found in locales/, messages/, lang/, i18n/ and translations/ folders (flat <locale>.json or namespaced <locale>/<namespace>.json), anywhere in the project except dependencies, build output, tests and fixtures. The source locale is --from, then sourceLocale in .babelize/config.json, then en. Glossary rules come from .babelize/config.json.

The locales checked are --locales, or else every locale file found plus the targetLocales in .babelize/config.json and every locale in the babelize translate lockfile, so a configured or previously translated language whose file is missing is an error, not silently skipped.

Options

FlagDescription
[path]Project directory (default: the current directory)
-f, --from <locale>Source locale
-l, --locales <locales>Only check these target locales, comma-separated
--strictFail on warnings too
--jsonPrint the full check as JSON: ok, errors, warnings, and every locale folder with its per-locale issues
--verboseList every issue (by default the first 20)

Exit codes

CodeMeaning
0No errors. Warnings don't fail the check unless --strict.
1Errors found (or warnings, with --strict)
2The path isn't a directory
4No locale files found, or none for the source locale

In CI

Run it on every pull request so a broken placeholder or a forgotten key never reaches users:

# .github/workflows/i18n.yml
name: i18n
on: pull_request
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npx @babelize/cli check

To fill in what's missing, run babelize translate again: it only translates new, changed and previously failed keys. Fix placeholder, ICU and plural errors in the locale file, or delete the entry and re-translate it.

Last updated: 2026-10-13

How is this guide?

On this page