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 works
lingui extractwrites your message catalogs, the same as today.- You open a pull request that adds or changes messages.
- The GitHub Action translates the keys that changed and commits the updated catalogs to the same PR.
lingui compilepicks 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
import { formatter } from "@lingui/format-po";
export default {
locales: ["en", "sv", "de"],
sourceLocale: "en",
catalogs: [
{
path: "src/locales/{locale}/messages",
include: ["src"]
}
],
format: formatter()
};
Lingui 6 removed the string form of format. It now takes a formatter function, and @lingui/format-po is a separate install (npm i -D @lingui/format-po). On Lingui 5 the string format: "po" still works. PO is the default either way, so omitting format entirely also works.
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 GitHub Action workflow
Run lingui extract before the Action so new messages are in the catalog when it runs:
.github/workflows/localhero-translate.yml (steps)
steps:
- uses: actions/checkout@v5
with:
ref: ${{ github.head_ref }}
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: '22'
- run: npm ci
- run: npx lingui extract
- uses: localheroai/localhero-action@v1
with:
api-key: ${{ secrets.LOCALHERO_API_KEY }}
Lingui 6 requires Node 22.19 or newer and ships ESM-only. Below that, lingui extract can exit without writing anything and without printing an error, which in CI reads as a green job that translated nothing. npm warns about the unmet engine; Yarn 1 and Bun do not, so the only symptom is an empty catalog. A Node 22 that is merely older than 22.19 is enough to trigger it.
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.
Last updated
Klar til å prøve?
Kom i gang på noen minutter. Du trenger ikke kredittkort.