Skip to content

LinguiJS + Locize

Compile-time React i18n with macros and ICU MessageFormat — paired with Locize for cloud translation management, AI translation, and CDN delivery.

LinguiJS (also known as js-lingui or just Lingui) is a JavaScript / TypeScript i18n library focused on compile-time extraction and a small runtime. You write translation calls as macros (t`Hello, ${name}` for components, defineMessage for plain strings), Lingui's CLI extracts them into message catalogs, and at runtime ICU MessageFormat handles plurals, selects, and interpolation.

Locize natively supports ICU MessageFormat at the platform level — which means LinguiJS projects work with Locize without any format conversion. Translators see the ICU syntax with plural/select handled directly in the value, the way Lingui expects it. The integration boils down to: extract → sync to Locize → translate → load back into Lingui (bundled or via CDN).

Key facts
  • Format: ICU MessageFormat (handled by Locize's format-messageformat package)
  • Runtime: Small (Lingui's main appeal vs i18next)
  • Workflow: Compile-time extraction → sync to Locize → translate → bundle or load via CDN
  • Example repo: locize-js-lingui-example
  • Best for: React projects that prefer build-time i18n with type safety + smaller runtime

How LinguiJS works in your code

A typical Lingui usage pattern in a React component — using the t macro for template strings and plural for plural-aware messages.

import { t } from '@lingui/macro'
import { useLingui } from '@lingui/react'

function Greeting ({ name }) {
  const { i18n } = useLingui()
  return <h1>{i18n._(t`Hello, ${name}!`)}</h1>
}

Plurals use ICU MessageFormat directly — no separate keys per plural form.

import { plural } from '@lingui/macro'

const message = plural(count, {
  one: '# item',
  other: '# items'
})

Connecting LinguiJS to Locize

Two common integration patterns:

  • CI-bundled (simpler): Run Lingui's extract in your CI pipeline → sync the message catalog to Locize via locize-cli → download translated catalogs in a later CI step → bundle them with your app. Translation updates require a rebuild, but the production runtime stays simple.
  • CDN-delivered (flexible): Use the locizer client to load translated catalogs from the Locize CDN at runtime, then pass them to Lingui's i18n.load + i18n.activate. Translation updates ship without a rebuild — same model as the continuous localization workflow.

Example of the CDN-delivered pattern:

// Load translations from Locize CDN into LinguiJS at runtime
import { i18n } from '@lingui/core'
import locizer from 'locizer'

locizer.init({
  projectId: '[your project id]',
  cdnType: 'standard'
})

locizer.loadAll('messages', (err, catalogs) => {
  if (err) return
  Object.keys(catalogs).forEach((locale) => {
    i18n.load(locale, catalogs[locale])
  })
  i18n.activate(locizer.lng)
})

Full working example.

Frequently asked questions

What is LinguiJS?

LinguiJS (often called Lingui or js-lingui) is a JavaScript / TypeScript internationalization library that uses compile-time macros to extract translation strings from your source code. You write a t-tagged template literal in JSX or defineMessage for non-component strings; a CLI extracts those messages into a catalog. At runtime, Lingui uses ICU MessageFormat for plurals, selects, and interpolation. It is popular in React projects that want type-safe, tree-shakable i18n with a smaller runtime than i18next.

Does Locize support LinguiJS?

Yes. LinguiJS uses ICU MessageFormat at runtime, and Locize supports ICU MessageFormat natively — at the i18n-format level — so Lingui projects work with Locize without any format conversion. The typical setup: run Lingui's extraction CLI to generate message catalogs, sync them to Locize (via locize-cli or the REST API), have translators / AI translation produce the translations in Locize, then download or load them at runtime in your Lingui-powered app.

How do I connect LinguiJS to Locize?

The simplest pattern: (1) use Lingui's `extract` command to pull source strings into a message catalog (typically per-locale JSON files); (2) sync those catalogs to your Locize project via locize-cli or the REST API as part of your CI pipeline; (3) translate them in Locize (humans, AI translation, or both with review workflow); (4) at runtime, load the translated catalogs into Lingui — either bundled at build time, or fetched from the Locize CDN via the locizer client. The example repo locize-js-lingui-example shows the end-to-end setup.

How does LinguiJS compare to i18next for use with Locize?

i18next has the deepest Locize integration — the i18next-locize-backend plugin handles runtime loading, saveMissing pushes new strings automatically, and the in-context editor uses i18next-subliminal for exact key matching. LinguiJS, by contrast, leans on compile-time extraction: the CLI generates message catalogs from your source code, and you sync those to Locize. The tradeoff is type safety, smaller runtime, and tree-shakable messages (Lingui) vs. richer runtime features and out-of-the-box CDN delivery (i18next + Locize backend). Both work well with Locize; the choice depends on your team's preference for build-time vs. runtime workflows.

Can I use LinguiJS with the Locize CDN?

Yes. The locizer client can load translated catalogs from the Locize CDN at runtime; you then pass those catalogs to Lingui's i18n instance via `i18n.load(locale, messages)` and `i18n.activate(locale)`. This means translation updates ship without a redeploy. The alternative — bundling the catalogs at build time after a CI sync — is simpler but requires a rebuild for every translation change.