|
Documentation
Book a DemoPlatform
PlatformMCPCLI
APIWorkflows
GuidesChangelog

Overview

  • @lingo.dev/cli

Getting started

  • Quickstart
  • Configuration
  • Examples

Reference

  • lingo push
  • lingo pull
  • lingo purge
  • Other commands

Configuration

  • Key controls
  • Formats
  • Locales

Guides

  • Adding a locale
  • Existing translations
  • Retranslation
  • Translator notes
  • Runs, state, and recovery
  • CI/CD
  • Monorepos
  • Large projects

Looking for the older CLI (v0)? See the legacy CLI docs

Example projects

Every example below is a real repository with .lingo/config.json committed and translations already in place, so you can read the config next to the output it produced. Most are runnable applications; a couple exist to show a file format on its own. Clone or fork one, run lingo link to bind your own engine, and push.

Pick an approach first#

There are two ways to localize with the CLI, and it decides which examples are relevant to you.

Translate the files you already have. Your framework keeps translations in its own format — Rails YAML, Android XML, Laravel PHP, ARB, Markdown — and the CLI translates those files in place. Nothing about your code changes. This is nine of the eleven examples below.

Author without keys. You wrap strings in l.text(...) where they appear, lingo extract builds a hash-keyed catalog for you, and there are no translation keys to name or maintain. That costs a build step and a runtime package, and it is what the two web app examples show.

Mobile apps#

ExampleFormatWhy this one
iOSxcode-xcstringsA String Catalog holds every locale, so the target path is the source path
AndroidandroidBare values/ as the source, and Android's own qualifiers (values-pt-rBR/)
Flutterflutter@-metadata and ICU placeholders kept, @@locale rewritten per file

Web apps#

The two keyless examples. Both wrap strings with l.text(...) and generate their catalog with lingo extract, so the middle column names the runtime package rather than a file format.

ExamplePackageWhy this one
React + Vite@lingo.dev/reactKeyless authoring; generated declarations narrow l.text() to extracted strings
Next.js@lingo.dev/react-nextKeyless authoring plus locale routing, hreflang, and a switcher. Pages Router

hreflang in production

LingoHead builds its hreflang URLs from a baseUrl prop that defaults to empty, so out of the box the tags are relative. Search engines expect absolute URLs — pass your site's origin (<LingoHead baseUrl="https://example.com" />) before relying on them.

Content and specs#

ExampleFormatWhy this one
Markdown docsmd, mdxProse by default, with frontmatter fields and MDX props opted in
Markdocmarkdoc, jsonNext.js content and UI strings in one push — three entries, different options each
OpenAPIyaml-openapiSummaries and descriptions only; paths, operation IDs and enums untouched

Framework catalogs#

ExampleFormatWhy this one
Railsyaml-root-keyThe locale is the YAML root key, so the root key itself is rewritten
Laravelphp, poLaravel catalogs plus a gettext file; :name placeholders preserved in both
TypeScript modulestypescriptCatalogs as TypeScript modules instead of JSON. The format only — no app consumes them

TypeScript catalogs need a default export

The typescript format reads a default export — export default { … }, with or without as const. A named export produces no translatable content, and the run completes having copied the source verbatim. So if a push reports files localized but roughly zero output tokens, check the export shape first.

Using one of these#

bash
npm install -g @lingo.dev/cli
lingo login
lingo link          # writes your own orgId and engineId into .lingo/config.json
lingo push --wait

None of the examples commit orgId or engineId — that keeps a fork from pushing through someone else's engine. lingo link fills both in locally.

If you want the GitHub App instead of the CLI

The GitHub App reads engineId from the .lingo/config.json committed in your repository — it resolves the organization from the App installation itself, but the engine has to be in the file. After forking, run lingo link and commit the updated config before installing the App.

Not every format has an example#

These eleven cover the frameworks people ask about most, but the CLI translates eighteen formats. xliff, srt, Xcode .strings and .stringsdict, generic yaml, and standalone JSON/JSONC all work without having a repository here — see Formats for the full list and the config each one needs.

Next steps#

Formats
All eighteen formats the CLI translates, including the ones without an example here
Configuration
Full .lingo/config.json reference
Quickstart
Install, authenticate, and run a first push in a few minutes
GitHub App
Translate on every push, server-side

Was this page helpful?

Mike ShulgaMike Shulga·Updated about 3 hours ago·3 min read