@shipi18n/cli
v1.1.4
Published
Command-line tool for translating locale files with Shipi18n
Maintainers
Readme
@shipi18n/cli
Command-line tool for translating locale files with Shipi18n.
🚀 Translate JSON files in seconds - One command, multiple languages!
Why Shipi18n CLI?
- Stop copy-pasting into Google Translate - One command translates to 100+ languages
- Placeholders stay intact -
{name},{{count}},%sare preserved automatically - Works with your existing setup - Drop into any React, Vue, Next.js, i18next project
- 90-day Translation Memory - Same content? Cached. No extra cost.
- Free tier included - 100 keys, 3 languages, no credit card required
Features
- ✅ Translate JSON files to 100+ languages with one command
- ✅ Preserve JSON structure - Nested objects, arrays, everything
- ✅ Placeholder preservation - Keep
{name},{{value}},%s, etc. intact - ✅ Key-based pricing - 100 free translation keys (unlimited characters!)
- ✅ Language limits enforced - FREE: 3 languages, STARTER: 10, PRO: unlimited
- ✅ ZIP output - Bundle translations into a single downloadable ZIP file
- ✅ Config file support - Save settings in
~/.shipi18n/config.yml - ✅ Translation Memory - Manage keys with
shipi18n keyscommands - ✅ Beautiful output - Colored, formatted terminal output
Quick Start
1. Install
npm install -g @shipi18n/cli2. Get Your Free API Key
Sign up at shipi18n.com - it takes 30 seconds!
Free tier includes:
- 100 translation keys
- 3 languages
- 10 requests/minute
- Unlimited characters
3. Configure
shipi18n config set apiKey YOUR_API_KEY4. Translate!
shipi18n translate en.json --target es,fr,deDone! You now have es.json, fr.json, and de.json in your ./locales folder.
Installation
Global (recommended)
npm install -g @shipi18n/cliLocal project
npm install --save-dev @shipi18n/cliThen use via npx:
npx shipi18n translate en.json --target es,frUsage
Translate Command
Translate a JSON locale file to multiple languages:
shipi18n translate <input> [options]Options:
-t, --target <languages>- Target languages (comma-separated, default:es,fr)-s, --source <language>- Source language (default:en)-o, --output <dir>- Output directory (default:./locales)--api-key <key>- API key (overrides config)--preserve-placeholders- Preserve placeholders (default:true)--html-handling <mode>- How to handle HTML in source text (default:none)none- Leave HTML as-isstrip- Remove all HTML tagsdecode- Decode HTML entities (&→&)preserve- Keep HTML tags and translate text between them
--no-fallback- Disable fallback to source for missing translations--no-regional-fallback- Disable regional fallback (e.g., pt-BR → pt)-i, --incremental- Only translate new/missing keys (skip existing translations)--skip-keys <keys>- Keys to skip from translation (comma-separated exact paths)--skip-paths <patterns>- Path patterns to skip (comma-separated, supports wildcards likenav.*)--context-file <path>- JSON file with context annotations for disambiguation--zip [filename]- Output translations as a single ZIP file (default:translations.zip)
Examples:
# Basic usage
shipi18n translate en.json --target es,fr
# Custom output directory
shipi18n translate en.json --target es,fr,de --output ./translations
# Specify source language
shipi18n translate ja.json --source ja --target en,es
# Use inline API key
shipi18n translate en.json --target es --api-key sk_live_...
# Translate with regional variants (pt-BR will fallback to pt if needed)
shipi18n translate en.json --target es,pt-BR,zh-TW
# Disable fallback (strict mode - fail if translation missing)
shipi18n translate en.json --target es --no-fallback
# Skip specific keys from translation (e.g., US state names, brand names)
shipi18n translate en.json --target es --skip-keys "states.CA,states.NY,company.name"
# Skip keys using glob patterns (e.g., all states, all config secrets)
shipi18n translate en.json --target es --skip-paths "states.*,config.*.secret"
# Combined - skip exact keys and patterns
shipi18n translate en.json --target es,fr \
--skip-keys "brandName" \
--skip-paths "states.*,internal.*"
# Output as ZIP file (default name: translations.zip)
shipi18n translate en.json --target es,fr,de --zip
# Output as ZIP with custom filename
shipi18n translate en.json --target es,fr,de --zip my-translations.zipFallback Behavior
By default, the CLI handles missing translations gracefully:
| Scenario | Default Behavior | |----------|-----------------| | Missing translation for a language | Uses source content (English) | | Missing regional variant (pt-BR) | Falls back to base language (pt), then source | | Missing translation for a key | Fills from source content |
Fallback output example:
✓ Translated to 3 languages!
✓ Saved: ./locales/es.json
✓ Saved: ./locales/pt-BR.json
✓ Saved: ./locales/zh-TW.json
Fallback information:
• pt-BR → pt (regional fallback)
• zh-TW → en (source fallback)
• es: 2 keys used fallback
- checkout.terms
- checkout.privacy
✨ Successfully translated 3 files!Disable fallback:
# Strict mode - no fallback to source
shipi18n translate en.json --target es --no-fallback
# Disable regional fallback only (pt-BR won't fall back to pt)
shipi18n translate en.json --target pt-BR --no-regional-fallbackSkipping Keys
Exclude specific keys or patterns from translation - useful for brand names, US state codes, or config values that should stay in English:
# Skip exact key paths
shipi18n translate en.json --target es --skip-keys "company.name,legal.terms"
# Skip using glob patterns
shipi18n translate en.json --target es --skip-paths "states.*,config.*.internal"Pattern Matching:
| Pattern | Matches |
|---------|---------|
| states.CA | Exact path only |
| states.* | states.CA, states.NY, etc. (single level) |
| config.*.secret | config.api.secret, config.db.secret |
| **.internal | Any path ending with .internal |
Example output with skipped keys:
✓ Translated 45 keys to 2 languages!
ℹ Skipped 5 key(s) from translation:
• states.CA
• states.NY
• states.TX
• company.name
• config.api.secret
✨ Successfully translated 2 files!Context Annotations
Improve translation quality for ambiguous words by providing context hints:
# Create a context file
echo '{"close": "button - dismiss window", "address": "form field - location"}' > context.json
# Translate with context
shipi18n translate en.json --target es --context-file context.jsonExample context.json:
{
"close": "button label - dismiss/shut a dialog",
"address": "form field - physical location/street address",
"post": "verb - publish content"
}Result: "close" → "Cerrar" (not "Cerca"), "address" → "Dirección" (not "Dirigirse")
Legal Content Warning
The CLI automatically warns when translating keys that may contain legal content:
⚠️ Legal content detected - review these keys:
• terms_of_service
• privacy_policy
• disclaimer
Machine-translated legal text may not be legally binding.Detected patterns: terms, privacy, disclaimer, legal, tos, eula, copyright, license, gdpr, cookie_policy, compliance, data_protection, refund, warranty
ZIP Output
Bundle all translations into a single ZIP file for easy distribution:
# Default filename (translations.zip)
shipi18n translate en.json --target es,fr,de,ja --zip
# Custom filename
shipi18n translate en.json --target es,fr,de,ja --zip locales-v2.zip
# With custom output directory
shipi18n translate en.json --target es,fr --zip --output ./dist/i18nOutput:
✔ Translated 50 keys to 4 languages!
✓ Saved: ./locales/translations.zip (4 files)
✨ Successfully translated 4 files!
Output: ./localesZIP structure:
translations.zip
├── es.json
├── fr.json
├── de.json
└── ja.jsonKeys Management
Manage your translation keys in Translation Memory:
# List all saved keys
shipi18n keys list
# Export keys to JSON
shipi18n keys export --format json --output keys.json
# Delete a specific key
shipi18n keys delete <keyId>Configuration
Manage CLI settings:
# Show current configuration
shipi18n config get
# Set API key
shipi18n config set apiKey YOUR_KEY
# Set default target languages
shipi18n config set targetLanguages es,fr,de
# Initialize config file with defaults
shipi18n config initHelp
# General help
shipi18n --help
# Command-specific help
shipi18n translate --help
shipi18n keys --help
shipi18n config --helpConfiguration File
The CLI stores settings in ~/.shipi18n/config.yml:
apiKey: sk_live_your_api_key_here
sourceLanguage: en
targetLanguages:
- es
- fr
- de
outputDir: ./locales
saveKeys: truePriority: Environment variables > Config file > Command-line options
Environment Variables
You can also configure via environment variables:
export SHIPI18N_API_KEY=sk_live_your_api_key_here
export SHIPI18N_SOURCE_LANG=en
export SHIPI18N_TARGET_LANGS=es,fr,de
export SHIPI18N_OUTPUT_DIR=./localesSupported Languages
Shipi18n supports 100+ languages including:
Popular:
- 🇪🇸 Spanish (es)
- 🇫🇷 French (fr)
- 🇩🇪 German (de)
- 🇯🇵 Japanese (ja)
- 🇨🇳 Chinese Simplified (zh)
- 🇨🇳 Chinese Traditional (zh-TW)
- 🇵🇹 Portuguese (pt)
- 🇷🇺 Russian (ru)
- 🇰🇷 Korean (ko)
- 🇮🇹 Italian (it)
See full list of 100+ supported languages
Pricing
| Tier | Price | Keys | Languages | Rate Limit | |------|-------|------|-----------|------------| | FREE | $0/mo | 100 | 3 | 10 req/min | | STARTER | $9/mo | 500 | 10 | 60 req/min | | PRO | $29/mo | 10K | 100+ | 300 req/min | | ENTERPRISE | Custom | Unlimited | Custom | 1000+ req/min |
What's a "key"? Each unique translation path (e.g., app.welcome) counts as one key. Translating to multiple languages doesn't multiply the count!
Examples
Real-World Workflow
# Your project structure
my-app/
├── locales/
│ └── en.json # ✅ You have this
└── src/
# Translate to multiple languages
$ shipi18n translate locales/en.json --target es,fr,de,ja
# Result
my-app/
├── locales/
│ ├── en.json # ✅ Original
│ ├── es.json # ✅ Spanish
│ ├── fr.json # ✅ French
│ ├── de.json # ✅ German
│ └── ja.json # ✅ Japanese
└── src/Input File (en.json)
{
"app": {
"title": "My Application",
"welcome": "Welcome, {username}!",
"description": "This is a demo"
},
"auth": {
"login": "Log In",
"logout": "Log Out"
}
}Output (es.json)
{
"app": {
"title": "Mi Aplicación",
"welcome": "¡Bienvenido, {username}!",
"description": "Esta es una demostración"
},
"auth": {
"login": "Iniciar Sesión",
"logout": "Cerrar Sesión"
}
}Notice how:
- ✅ JSON structure is preserved
- ✅ Placeholders like
{username}are kept intact - ✅ Only values are translated, keys stay in English
CI/CD Integration
GitHub Actions
name: Translate Locales
on: [push]
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install Shipi18n CLI
run: npm install -g @shipi18n/cli
- name: Translate
env:
SHIPI18N_API_KEY: ${{ secrets.SHIPI18N_API_KEY }}
run: shipi18n translate locales/en.json --target es,fr,de
- name: Commit translations
run: |
git config user.name "github-actions"
git config user.email "[email protected]"
git add locales/
git commit -m "Update translations" || echo "No changes"
git pushNPM Scripts
Add to your package.json:
{
"scripts": {
"translate": "shipi18n translate locales/en.json --target es,fr,de",
"translate:dev": "shipi18n translate locales/en.json --target es",
"translate:all": "shipi18n translate locales/en.json --target es,fr,de,ja,zh,pt,ru,ko"
}
}Then run:
npm run translateTroubleshooting
"API key not found"
# Set your API key
shipi18n config set apiKey YOUR_KEY
# Or use environment variable
export SHIPI18N_API_KEY=YOUR_KEY
# Get your key at https://shipi18n.com"Language limit exceeded"
The FREE tier allows 3 languages. Upgrade your plan:
- STARTER ($9/mo) - 10 languages
- PRO ($29/mo) - 100+ languages
"Rate limit exceeded"
Wait a minute or upgrade your plan for higher rate limits.
"Invalid JSON"
Make sure your input file is valid JSON:
# Validate JSON
cat en.json | jq .Development
# Clone the repo
git clone https://github.com/Shipi18n/shipi18n-cli.git
cd shipi18n-cli
# Install dependencies
npm install
# Test locally
node bin/shipi18n.js translate test.json --target es,fr
# Link globally for testing
npm link
shipi18n --helpDocumentation & Resources
📚 Full Documentation: shipi18n.com/integrations/cli
| Resource | Link | |----------|------| | Getting Started | shipi18n.com | | API Reference | shipi18n.com/api | | i18next Best Practices | shipi18n.com/integrations/react | | Blog & Tutorials | shipi18n.com/blog |
Related Packages
| Package | Description | |---------|-------------| | @shipi18n/api | Node.js SDK for programmatic use | | vite-plugin-shipi18n | Vite plugin for build-time translation | | i18next-shipi18n-backend | i18next backend for dynamic loading | | shipi18n-github-action | GitHub Action for CI/CD |
Examples
- Node.js Example - Basic usage examples
- Vue Example - Vue 3 + vue-i18n integration
License
MIT
