| title | Getting Started |
|---|---|
| sidebar_position | 2 |
Lingo Tracker helps you track, validate, and manage translations across projects. This guide shows how to install the CLI, initialize a project, and add collections.
Node.js >= 22.16 is required. Install the CLI as a dev dependency in your project.
pnpm add -D @simoncodes-ca/lingo-trackernpm install --save-dev @simoncodes-ca/lingo-trackeryarn add -D @simoncodes-ca/lingo-trackerOnce installed, use the npx lingo-tracker command to interact with the CLI.
Run this in your project root to create a .lingo-tracker.json with a sensible default setup:
npx lingo-tracker init \
--collection-name Main \
--translations-folder src/assets/i18n \
--base-locale en \
--locales en fr-ca es \
--setup-bundle true \
--bundle-dist ./src/assets/i18n \
--bundle-name "{locale}" \
--type-dist-file ./src/generated/translation-tokens.tsWhat each flag does:
| Flag | Value | Why |
|---|---|---|
--collection-name |
Main |
Name for the initial translation collection |
--translations-folder |
src/assets/i18n |
Where LingoTracker stores its internal JSON source files |
--base-locale |
en |
Authoring language — the locale you write source strings in |
--locales |
en fr-ca es |
All locales your app supports (adjust to your needs) |
--bundle-dist |
./src/assets/i18n |
Output directory for the runtime bundle files Transloco loads |
--bundle-name |
{locale} |
Output filename pattern — produces en.json, fr-ca.json, etc. |
--type-dist-file |
./src/generated/translation-tokens.ts |
Enables TypeScript token generation for type-safe translation keys |
After running this command, lingo-tracker bundle will produce en.json, fr-ca.json, and es.json in src/assets/i18n, and a typed translation-tokens.ts constant file in src/generated/.
See Initialize a project below for the full option reference, and the Bundle Generation Guide for bundle configuration details.
If you use Claude Code (or a compatible AI assistant), install the Lingo Tracker skill to enable guided i18n workflows — detecting hardcoded strings, creating translation resources, and updating components to use Transloco:
npx lingo-tracker install-skillThis writes a skill file to your project that Claude Code picks up automatically. See install-skill in the CLI Reference for details.
The lingo-tracker package ships a built-in API server that hosts the Lingo Tracker web interface.
Then start the app server:
npx lingo-tracker-appThe server listens on port 3030 by default.
Pass --port to override the port:
npx lingo-tracker-app --port 4000Or set the LINGO_TRACKER_PORT environment variable. The --port flag takes precedence over the environment variable:
{
"scripts": {
"lingo-tracker-app": "lingo-tracker-app --port 4000"
}
}Run in your project root to create .lingo-tracker.json:
lingo-tracker initIf you run it interactively, you will be prompted for missing values. In non‑interactive environments, pass the required options.
- Required when non‑interactive:
--collection-name,--translations-folder - All options:
--collection-name <name>: Name of the initial collection key (e.g., "Main").--translations-folder <path>: Path to the translations directory for this collection.--export-folder <path>: Output folder for exports. Default:dist/lingo-export.--import-folder <path>: Input folder for imports. Default:dist/lingo-import.--base-locale <locale>: Base/authoring locale. Default:en.--locales <locales...>: Supported locales list. Example:en fr-ca es de.--setup-bundle <true|false>: Customize the default bundle configuration.--bundle-dist <path>: Bundle output directory. Default:./src/assets/i18n.--bundle-name <pattern>: Bundle name pattern. Default:{locale}.--token-casing <casing>: Token key casing (upperCaseorcamelCase).--type-dist-file <path>: Path for generated TypeScript type definitions.--token-constant-name <name>: Custom name for the generated TypeScript constant.
Example (CI-safe, no prompts):
lingo-tracker init \
--collection-name Main \
--translations-folder apps/web/src/assets/i18n \
--export-folder dist/lingo-export \
--import-folder dist/lingo-import \
--base-locale en \
--locales en fr-ca es deExample with bundle customization:
lingo-tracker init \
--collection-name Main \
--translations-folder apps/web/src/assets/i18n \
--base-locale en \
--locales en fr-ca es de \
--setup-bundle true \
--bundle-dist ./src/assets/i18n \
--token-casing camelCase \
--type-dist-file ./src/generated/tokens.tsInitialization writes a JSON config named .lingo-tracker.json at your project root. Structure:
{
"exportFolder": "dist/lingo-export",
"importFolder": "dist/lingo-import",
"baseLocale": "en",
"locales": [
"en"
],
"collections": {
"Main": {
"translationsFolder": "apps/web/src/assets/i18n"
}
},
"bundles": {
"main": {
"bundleName": "{locale}",
"dist": "./src/assets/i18n",
"collections": "All"
}
}
}- Global fields (
exportFolder,importFolder,baseLocale,locales) apply to all collections by default. - Each collection requires
translationsFolder. A collection may override any global field locally if needed. - A default
bundlessection is always created during init. If you customize the bundle, additional fields liketypeDistFile,tokenCasing, andtokenConstantNamemay be present. See the Bundle Generation Guide for details.
Collection shape:
{
"translationsFolder": "path/to/translations",
"exportFolder": "optional/override",
"importFolder": "optional/override",
"baseLocale": "en",
"locales": ["en", "fr-ca"]
}Use add-collection to register more translation sources within the same repo. This reuses global defaults and only persists overrides when they differ.
lingo-tracker add-collection- Required when non‑interactive:
--collection-name,--translations-folder - All options (same meanings as
init):--collection-name <name>--translations-folder <path>--export-folder <path>--import-folder <path>--base-locale <locale>--locales <locales...>
Examples:
- Simple, rely on global defaults:
lingo-tracker add-collection \
--collection-name Admin \
--translations-folder apps/admin/src/assets/i18n- Override per-collection settings (only differences are saved under the collection):
lingo-tracker add-collection \
--collection-name Mobile \
--translations-folder apps/mobile/src/i18n \
--base-locale en-GBNotes:
- If
.lingo-tracker.jsonis missing or invalid, the command will exit with a helpful message. - If the collection name already exists, the command will refuse to overwrite.
Both commands support fully non‑interactive runs; provide all required flags to avoid prompts. The CLI auto‑detects TTY and will throw if a required option is missing in non‑interactive mode.
- Required flags in CI:
init:--collection-name,--translations-folder(others optional)add-collection:--collection-name,--translations-folder
- Install
lingo-tracker - Run
lingo-tracker initonce in the repo - Add more collections with
lingo-tracker add-collection - Commit
.lingo-tracker.json
That's it. You're ready to track and manage translations with Lingo Tracker.
After setting up your project, you may need to normalize your translation files to ensure consistency. Normalization is particularly useful in these scenarios:
After Manual Edits If you or your team manually edit JSON translation files, checksums and statuses may become outdated. Normalization recomputes all checksums and updates statuses accordingly.
After Adding New Locales
When you add a new locale to your configuration (e.g., adding de to your locales list), existing resources won't have entries for the new locale. Normalization creates these missing entries with the base value and marks them as new.
After Importing Translations External translation tools or services may provide translations without proper metadata. Normalization ensures all entries have correct checksums and statuses.
Periodic Maintenance Running normalize periodically helps maintain consistency and cleans up your folder structure by removing empty directories.
When Statuses Seem Wrong
If translation statuses don't match reality (e.g., translations marked as stale when they shouldn't be), normalization corrects these based on actual checksums.
The normalize command performs these operations:
- Recomputes Checksums: Updates MD5 checksums for the base locale and all translations to reflect current values
- Adds Missing Locales: Creates entries for any configured locales that don't exist in a resource, using the base value with status
new - Updates Statuses: Sets correct translation statuses based on checksums:
new- Locale entry was just added or matches the base valuestale- Base value changed since the translation was last updatedtranslated/verified- Preserved when base value hasn't changed
- Creates Missing Files: Ensures both
resource_entries.jsonandtracker_meta.jsonexist at every folder level - Cleans Up Empty Folders: Removes directories that no longer contain translation entries
Normalization automatically removes empty folders to keep your translations directory clean and organized:
-
Empty Folder Definition: A folder is considered empty if it has:
- No
resource_entries.jsonfile, OR - An empty
resource_entries.json(no entries or{}), AND - No subfolders containing entries
- No
-
What Gets Removed:
- Folders with only
tracker_meta.json(metadata without entries) - Folders with only hidden files like
.gitkeepor.DS_Store - Parent folders that become empty after their children are removed
- Folders with only
-
What's Protected:
- The root translations folder is never removed, even if empty
- Any folder containing
resource_entries.jsonwith actual entries - Any folder with subfolders that contain entries
-
Bottom-Up Cleanup: The cleanup process starts with the deepest folders and works up to the root, allowing recursive removal of entire empty folder trees
Preview what would change (recommended first step):
lingo-tracker normalize --collection Main --dry-runNormalize a specific collection:
lingo-tracker normalize --collection MainNormalize all collections:
lingo-tracker normalize --allGet JSON output for automation:
lingo-tracker normalize --collection Main --jsonAfter normalization, you'll see a summary like this:
🔄 Normalizing collection: Main
✅ Entries processed: 42
✅ Locales added: 7
✅ Files created: 2
✅ Files updated: 15
✅ Folders removed: 3
- Entries processed: Total number of translation resources examined
- Locales added: Number of missing locale entries that were created
- Files created: Number of new JSON files created (resource_entries.json or tracker_meta.json)
- Files updated: Number of existing files that had metadata updated
- Folders removed: Number of empty folders that were deleted
- Use Dry-Run First: Always run with
--dry-runto preview changes before applying them - Commit Before Normalizing: Ensure you have a clean Git state so you can review changes
- Normalize After Config Changes: Any time you modify locale settings, run normalize to update all resources
- Regular Maintenance: Consider adding normalize to your CI/CD pipeline or running it periodically
- Check Folder Cleanup: Review the "Folders removed" count to understand what's being cleaned up
Normalization is designed to be safe:
- Preserves Translation Values: Never modifies existing translation text
- Preserves Comments and Tags: Keeps all metadata intact
- Only Adds/Corrects: Fills in missing data and fixes incorrect metadata
- Dry-Run Available: Preview all changes before applying
LingoTracker can automatically translate new resources using machine translation providers such as Google Translate. To enable this, add a translation block to your .lingo-tracker.json:
{
"translation": {
"enabled": true,
"provider": "google-translate",
"apiKeyEnv": "GOOGLE_TRANSLATE_API_KEY"
}
}Then set the API key in your environment:
export GOOGLE_TRANSLATE_API_KEY="your-api-key-here"Auto-translation handles plain text and simple placeholders ({name}, {{ count }}). Strings with complex ICU syntax (plural, select, number, date, time) are skipped and left for human translators.
For full details on configuration, ICU handling, and best practices, see the Auto-Translation Guide.
- For managing translation resources and other CLI commands, see the CLI Reference
- For programmatic access via REST API, see the API Reference
- For setting up machine translation, see the Auto-Translation Guide