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.
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.
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#
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#
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.
