Web App Localization

Updated: last week · 4 min read

The Lingo.dev CLI translates your web app's resource files - JSON, YAML, XLIFF, PO, or PHP - through a configured localization engine. Set up i18n in your framework, point the CLI at your translation files, and run.

How It Works#

Every web framework has an i18n library that loads translations from resource files - JSON for React, XLIFF for Angular, PO for Django, and so on. The CLI translates those files directly, so the framework picks up translations without any code changes.

1

Set up i18n in your framework

Use your framework's official i18n library to add locale-aware routing, a translation function, and source-language resource files. Each framework section below links to the official setup guide.

2

Configure the CLI

Run lingo init to create a .lingo/config.json with your source and target locales plus the file patterns to translate, then lingo link to attach your organization and engine. The CLI auto-detects each file's format from its extension, so no bucket type is needed. Commit .lingo/config.json.

3

Run translations

Run lingo push and the CLI translates your resource files through the localization engine - glossary rules, brand voice, and model selection apply automatically.

Prerequisites#

Install the CLI and authenticate:

bash
npm install -g @lingo.dev/cli
lingo login

The CLI requires Node.js 22+. In CI, skip the interactive login and pass a key with --api-key or the LINGO_API_KEY environment variable.

Every CLI run sends content through a localization engine - the configuration that determines which LLM model, glossary, brand voice, and rules apply. Create one in the Lingo.dev dashboard and generate an API key. lingo link writes the engine's orgId and engineId into .lingo/config.json.

JavaScript Frameworks#

The locale segment in each pattern is substituted per target locale - public/locales/en/translation.json becomes public/locales/de/translation.json, and so on. The source path must contain the source locale code.

react-i18next loads translations from JSON files and provides a useTranslation hook that maps keys to translated strings at runtime.

json
{
  "orgId": "org_...",
  "engineId": "eng_...",
  "sourceLocale": "en",
  "targetLocales": ["es", "fr", "de", "ja"],
  "files": [{ "pattern": "public/locales/en/translation.json" }]
}

Server-Side Frameworks#

Laravel ships with built-in localization that loads translations from PHP files organized by locale directory.

json
{
  "orgId": "org_...",
  "engineId": "eng_...",
  "sourceLocale": "en",
  "targetLocales": ["es", "fr", "de", "ja"],
  "files": [{ "pattern": "lang/en/messages.php" }]
}

Running Translations#

With .lingo/config.json in place, translate all resource files in one command:

bash
lingo push --wait

The CLI reads your source locale files, computes what changed since the last run using the lockfile (.lingo/lock.json, committed alongside your config), translates only the delta, and writes results to target locale files. Existing translations are preserved - the CLI only fills in missing or updated strings.

On the first run, or after adding a new target locale, translate everything from scratch:

bash
lingo push --backfill-missing --wait

Scope a run to a subset of files by passing a glob:

bash
lingo push "messages/**"

To collect the last run pushed from this checkout without translating again, run lingo pull; other machines get the translations once they're committed. Use lingo check as a deploy gate to verify translations are up to date.

Next Steps#