LinguiJS

Localhero.ai translates Lingui projects through the .po catalogs Lingui already produces. There is no SDK and no plugin: the catalog file is the integration, so your extract and compile steps stay exactly as they are.

How it fits your workflow

  1. lingui extract writes your message catalogs, the same as today.
  2. You open a pull request that adds or changes messages.
  3. The GitHub Action translates the keys that changed and commits the updated catalogs to the same PR.
  4. lingui compile picks up the result in your build.

Nothing in your build has to know Localhero.ai exists. Both generated IDs and explicit IDs (js-lingui-explicit-id) work.

Setup

1. Use the PO format in Lingui

Point Lingui at po catalogs (Lingui's default) in your lingui.config.js:

lingui.config.js
export default {
  locales: ["en", "sv", "de"],
  sourceLocale: "en",
  catalogs: [
    {
      path: "src/locales/{locale}/messages",
      include: ["src"]
    }
  ],
  format: "po"
};

2. Initialize the project

The CLI detects lingui.config.js and suggests the right file paths:

npx @localheroai/cli init

The resulting localhero.json points at your catalog directory with a **/*.po pattern. See Project Setup for all options.

3. Add the workflow

Run lingui extract before the Action so new messages are in the catalog when it runs:

.github/workflows/localhero.yml (steps)
steps:
  - uses: actions/checkout@v4
    with:
      ref: ${{ github.head_ref }}
      fetch-depth: 0

  - uses: actions/setup-node@v4
    with:
      node-version: '20'

  - run: npm ci
  - run: npx lingui extract

  - uses: localheroai/localhero-action@v1
    with:
      api-key: ${{ secrets.LOCALHERO_API_KEY }}

The full workflow file, including triggers and permissions, is in the GitHub Actions guide.

ICU plurals

Lingui expresses plurals as ICU MessageFormat inside a single message. Translations come back in each target language's own CLDR plural categories, not a copy of the source language's set:

English source → Polish translation
{count, plural, one {# item in your cart} other {# items in your cart}}

{count, plural, one {# produkt w Twoim koszyku}
                few {# produkty w Twoim koszyku}
                many {# produktów w Twoim koszyku}
                other {# produktu w Twoim koszyku}}

Arabic gets all six categories, Japanese collapses to just other, and exact matches like =0 are preserved.

Comparing tools? We surveyed the platforms that document react-i18next and LinguiJS support in our comparison of translation tools for both libraries.

Klar til å prøve?

Kom i gang på noen minutter. Du trenger ikke kredittkort.