comvi push
The comvi push command uploads local translation files to the Comvi platform. Use it to sync translations that developers add in code back to the platform where translators can review and translate them into other languages.
Prerequisites
Section titled “Prerequisites”You need a .comvirc.json file in your project root and an API key. Prefer COMVI_API_KEY for the key:
{ "apiBaseUrl": "https://api.comvi.io", "translationsPath": "./src/locales", "fileTemplate": "{namespace}/{languageTag}.json", "format": "json"}Basic Usage
Section titled “Basic Usage”comvi pushThis reads all translation files from the configured translationsPath and uploads them to your Comvi project. Conflict handling is controlled by --force-mode.
Options
Section titled “Options”comvi push [options]| Option | Alias | Default | Description |
|---|---|---|---|
--config | -c | .comvirc.json | Path to the Comvi config file |
--locale | -l | All detected locales | Comma-separated list of locale tags to upload |
--ns | -n | All detected namespaces | Comma-separated list of namespaces to upload |
--path | -p | .comvirc.json → translationsPath | Source directory containing translation files |
--dry-run | false | Preview changes without uploading anything | |
--force-mode | .comvirc.json → push.forceMode or 'ask' | Conflict resolution: override, keep, ask, or abort |
Source File Structure
Section titled “Source File Structure”The CLI expects files laid out by the configured fileTemplate, matching the structure comvi pull produces. With the default template ({namespace}/{languageTag}.json), the default namespace is stored at the root as {languageTag}.json, and every other namespace gets its own subdirectory:
src/locales/├── en.json # default namespace (root)├── de.json├── fr.json├── common/│ ├── en.json│ ├── de.json│ └── fr.json└── auth/ ├── en.json └── de.jsonEach JSON file contains flat or nested key-value pairs:
{ "greeting": "Hello, {name}!", "nav.home": "Home", "nav.settings": "Settings"}With the default template the CLI detects the namespace from the directory (root = default namespace) and the language from the filename. A custom fileTemplate is matched literally, so the layout follows whatever placeholders you configure.
Dry Run
Section titled “Dry Run”Always preview what will change before pushing to the platform. The --dry-run flag prints a summary of how many keys would be created, updated, and how many conflict with existing platform values — without uploading anything. Push never deletes keys, so dry-run never reports deletions:
comvi push --dry-runExample output:
📦 Push preview (dry run): ✅ Created: 3 keys 📝 Updated: 1 translations ⚠️ Conflicts: 0 keysWhen conflicts are detected, the preview also tells you how to resolve them:
📦 Push preview (dry run): ✅ Created: 3 keys 📝 Updated: 1 translations ⚠️ Conflicts: 2 keys
Run with --force-mode override to overwrite remote values. Run with --force-mode keep to upload only non-conflicting values.Conflict Handling
Section titled “Conflict Handling”When a key already exists on the platform, --force-mode controls what happens. The default is ask, which prompts interactively in a terminal. Use a non-interactive mode in CI pipelines.
| Mode | Behaviour |
|---|---|
ask | Count conflicts and prompt for override, keep, or abort (requires a TTY) |
override | Local values replace existing platform translations |
keep | Existing platform translations are preserved; only new keys are created |
abort | Stop immediately if any conflict is detected; nothing is written |
New keys are always created regardless of mode.
Using --force-mode
Section titled “Using --force-mode”# Preview first, then overridecomvi push --dry-runcomvi push --force-mode override
# Push only new keys — never touch existing translator workcomvi push --force-mode keep
# Fail fast if anything would conflict (useful in strict CI)comvi push --force-mode abortPushing Specific Locales
Section titled “Pushing Specific Locales”Upload only certain locales:
# Push only the source languagecomvi push --locale en
# Push English and Germancomvi push -l en,dePushing Specific Namespaces
Section titled “Pushing Specific Namespaces”Upload only certain namespaces:
# Push only the common namespacecomvi push --ns common
# Push common and auth namespacescomvi push -n common,authCI/CD Usage
Section titled “CI/CD Usage”Push translations from your main branch after a merge so that new keys are immediately available to translators:
name: Push Translationson: push: branches: [main] paths: - 'src/locales/en/**'
jobs: push: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 - run: npm ci - run: npx comvi push --locale en env: COMVI_API_KEY: ${{ secrets.COMVI_API_KEY }}This workflow triggers only when the source language files change on main, pushing new and updated keys to the platform for translators.
Configuration File Reference
Section titled “Configuration File Reference”All push options can be set in .comvirc.json:
{ "apiBaseUrl": "https://api.comvi.io", "translationsPath": "./src/locales", "fileTemplate": "{namespace}/{languageTag}.json", "format": "json", "push": { "forceMode": "ask" }}Command-line flags override config file values.
Next Steps
Section titled “Next Steps”- comvi pull — download translations from the platform
- comvi typegen — generate TypeScript types after pushing new keys
- CLI Overview — all CLI commands and global configuration
- CI/CD Integration — full pipeline examples