React Intl (FormatJS) + Polylens

Translation health for React Intl (FormatJS), caught in CI

Score your React Intl message files on every push and fail the build when a locale regresses.

React Intl (FormatJS) falls back to the default message or the message id when a translation is missing, so an untranslated id ships without an error. Extraction and compilation steps make gaps easy to miss across locales.

Polylens scans your compiled FormatJS message JSON, scores each locale, and lists every missing message, broken ICU argument, malformed plural and stale string, then fails CI on regression. One curl call, strings stay in your repo.

Locale format: JSON message catalogs (lang/{locale}.json). Point the gate at your compiled message catalog directory.

React Intl (FormatJS) bugs that ship with a green build

Missing messages fall back to defaults

FormatJS uses the default message or id when a translation is absent. Polylens flags every missing message per locale.

Broken ICU arguments

A translator who drops {count} or {name} breaks the formatted output. Polylens diffs every ICU argument.

Malformed plurals and selects

An ICU plural that loses a branch renders raw syntax. Polylens validates every plural and select block.

Stale translations

A reworded source leaves old translations live. Polylens detects staleness from scan history alone.

GitHub Actions: gate React Intl messages on every PR

name: i18n health
on:
  pull_request:
    paths: ['lang/**']
jobs:
  polylens:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: curl -fsSO https://polylens.sh/polylens-ci.mjs
      - run: node polylens-ci.mjs ./lang
        env:
          POLYLENS_TOKEN: ${{ secrets.POLYLENS_TOKEN }}
          FAIL_ON: error
          NO_REGRESSION: 'true'

Add your project token as the POLYLENS_TOKEN repository secret. A failing gate returns HTTP 422, so the build goes red like any other test.

FAQ

How do I check React Intl translations in CI?

Add one step to your pipeline that posts your locale files to Polylens. The gate returns HTTP 422 when a language regresses, so the build fails like any other test. No SDK, one curl call, and your strings never leave your repo.

Will it catch missing keys that React Intl renders as raw strings?

Yes. Missing keys are the first of 13 issue classes Polylens detects, alongside broken placeholders, untranslated copy, malformed plurals, and stale strings. Every missing key is listed per language in the dashboard.

Is Polylens a replacement for React Intl?

No. React Intl renders your translations at runtime; Polylens is the quality gate that scores the locale files before they ship. They sit on opposite ends of the pipeline and work together.

Wire React Intl (FormatJS) into a CI gate in ten minutes. Free for one project, no card, strings stay in your repo.