The Lingo.dev CLI runs in any CI/CD environment with Node.js. Add it as a pipeline step to translate on every push - the lockfile ensures only changed strings are processed, so translations stay fast and cost-efficient as your project grows.
On GitHub? Two ways to run
The GitHub App is the easiest option on GitHub - install it once and it reacts to pushes and pull requests automatically. No runner, no API key secret, and no lockfile; you configure the repository with .lingo/config.json and an engineId.
The GitHub Action and the other integrations below run the CLI inside your own pipeline using i18n.json, an i18n.lock lockfile, and a LINGODOTDEV_API_KEY secret. Use this path when you want translation to run alongside other CI steps, or when you're not on GitHub.
The rest of this guide covers the GitHub Action and CLI.
How It Works#
The CI/CD pipeline runs the CLI as a step after checkout. The CLI reads your i18n.json configuration, compares source files against the lockfile to identify changes, translates the delta through a configured localization engine, and writes results to target locale files. The pipeline then commits the translated files or opens a pull request - depending on your workflow preference.
Choose Your Workflow#
Four workflow patterns cover most team structures. Start with the simplest and graduate as your team grows.
| Workflow | How it works | Best for | Trade-off |
|---|---|---|---|
| Commit to main | Translates and commits directly to main | Small teams, zero friction | No review step for translations |
| PR from main | Translates and opens a PR for review | Teams that review translations | Requires manual PR approval |
| Commit to feature branch | Translates on feature branch push | Long-lived feature branches | Translation commits in branch history |
| PR from feature branch | Translates and opens PR from feature branch | Maximum control per feature | Multiple PRs per feature |
Starting recommendation
Commit to main works well for most teams. Translations ship with every push, the lockfile ensures consistency, and the localization engine's glossary and brand voice rules handle quality. Move to PR-based workflows when you need human review of translations.
Quick Setup#
Store your Lingo.dev API key as a CI/CD secret, then add the translation step to your pipeline.
Lingo.dev provides an official GitHub Action that handles checkout, translation, and commit/PR creation.
Prefer not to manage a workflow file, an API key secret, or a lockfile? The GitHub App does continuous localization on GitHub with none of that - install once and configure .lingo/config.json.
Commit to main:
name: Translate
on:
push:
branches: [main]
permissions:
contents: write
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: lingodotdev/lingo.dev@main
with:
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}PR from main - add pull-request: true and a GH_TOKEN:
name: Translate
on:
push:
branches: [main]
permissions:
contents: write
pull-requests: write
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: lingodotdev/lingo.dev@main
with:
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
pull-request: true
env:
GH_TOKEN: ${{ github.token }}See the full GitHub Actions integration guide for feature branch workflows, custom commit messages, monorepo support, and GPG signing.
Translation Verification#
The --frozen flag and the lockfile are part of the GitHub Action and CLI. The GitHub App tracks translation state server-side and has no lockfile or --frozen equivalent.
Use the --frozen flag as a deployment gate to ensure no untranslated content ships to production. The CLI exits with a non-zero status if any strings need translation.
npx lingo.dev@latest run --frozenAdd this as a separate pipeline step that runs before deploy:
- name: Verify translations
run: npx lingo.dev@latest run --frozenMonorepo Workflows#
For monorepos with multiple packages that each have their own translation files, use the working-directory option to target specific packages:
- uses: lingodotdev/lingo.dev@main
with:
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
working-directory: apps/webMerge Conflicts#
This applies to the GitHub Action and CLI. The GitHub App does not use a lockfile, so it has no i18n.lock conflicts to resolve.
The lockfile (i18n.lock) may conflict when branches with translation changes merge. The resolution is straightforward - delete the conflicting lockfile, complete the merge, and regenerate it:
git merge feature-branch
rm i18n.lock
git add .
git merge --continue
npx lingo.dev@latest lockfile --forceThe lockfile --force command rebuilds the lockfile from the current state of your source files without triggering new translations. See the advanced integration patterns guide for rebase-based resolution and conflict prevention strategies.
