How do I set up the CLI and scan my project?
The Better i18n CLI lets you scan your codebase, sync keys, and publish translations from the terminal.
Installation #
npm install -g @better-i18n/cli
# or
bun add -g @better-i18n/cliThe binary is better-i18n.
Authentication #
better-i18n loginThe key is stored at ~/.better-i18n/auth.json. better-i18n whoami prints who you are and where the credential came from — the file, or the BETTER_I18N_API_KEY environment variable, which takes over in CI.
You can also grab a key by hand from Settings → API Keys in the dashboard.
Configuration #
The CLI reads your project from i18n.config.ts (or .js) — the same config your SDK uses, so there is usually nothing new to create. It is looked for in the working directory first, then in subdirectories.
export const project = "your-org/your-project";
export const defaultLocale = "en";Both project and projectId are accepted for the "org/project" value; the dashboard shows the name either way.
Core commands #
scan — find translation keys in your code #
better-i18n scanReads your source files for t() calls and reports what it found. Changes nothing.
sync — push keys to Better i18n #
better-i18n syncCreates keys found in your code; unchanged keys are skipped.
pull — bring remote translations back down #
better-i18n pullcheck — missing and unused keys #
better-i18n check # interactive
better-i18n check:missing # in code, not in the project
better-i18n check:unused # in the project, not found in codeAll three take --format eslint|json (default eslint), --dir <path> and --verbose. The json format is the one to use in CI, since you can act on it.
publish — push translations to the CDN #
better-i18n publish:status # what is pending
better-i18n publish # publish itpublish:status first is a habit worth having — it is the difference between publishing what you meant and publishing what happened to be pending.
doctor — health check #
better-i18n doctorOther commands #
| Command | What it does |
|---|---|
projects · project | List projects · show one project's languages, namespaces, coverage |
keys list · keys create · keys delete | Manage keys directly |
translate | Set translations for existing keys (JSON on stdin) |
translations | Fetch translations with their full text |
languages add · languages edit | Add target languages · change a language's status |
syncs list · syncs get <id> · syncs cancel <id> | Sync/publish job history |
content:types | Generate types for your Content CMS models |
whoami · logout | Session |
CI/CD integration #
# GitHub Actions
- name: Check i18n health
run: better-i18n check:missing --format json
env:
BETTER_I18N_API_KEY: ${{ secrets.BETTER_I18N_API_KEY }}The command exits non-zero when it finds problems, which is what fails the step — there is no --fail-on-* flag to add.
Using environment variables #
export BETTER_I18N_API_KEY=bi-...
better-i18n syncAn account key looks like bi-…; content delivery keys look like bi_pub_… and are read-only, so the CLI wants the former.
Better I18N