i18nize
🧠 Automatically fills in missing I18n YAML keys using DeepL translation API. Designed to streamline multi-language support in Ruby and Rails projects.
✨ Features
- Detects missing or empty translation keys in locale files
- Supports multiple YAML files and nested directories (e.g.
config/locales/api/en.yml) - Automatically translates from a source locale (default:
en) to a target (e.g.cs) - Placeholder mode to fill only blank/missing keys without DeepL (
--only_blank) - Integrates with DeepL API (Free or Pro)
- Safely merges translations into corresponding
*.ymlfiles - Handles structural conflicts by overwriting target with source truth
- Character count check with confirmation prompt
- CLI (
i18nize)
🔧 Installation
Add this line to your application's Gemfile:
gem "i18nize"
Then run:
bundle install
Or install manually:
gem install i18nize
🚀 Usage
1. Set your DeepL API key
Create a .env file (loaded automatically if you use dotenv) or export it in your shell:
export DEEPL_API_KEY=your-api-key
export DEEPL_ENDPOINT=https://api.deepl.com/v2/translate # Only if you are using a DeepL Pro account
👉 You can use the Free DeepL API.
2. Run translations via CLI
# Translate from en → cs
i18nize cs
# Translate from de → fr
i18nize fr --from de
💬 This will:
- Scan
config/locales/**/*en.yml(or your chosen source language) - Detect which
cs.ymlfiles are missing keys - Use DeepL to translate missing values
- Write them to the appropriate files (creating them if needed)
3. Show missing keys only
# Missing cs keys (source en)
i18nize cs --missing
# Missing cs keys (source de)
i18nize cs --missing de
This mode only lists missing keys, no translations are written.
4. Fill placeholders for blank/missing keys (no DeepL)
# Insert placeholders instead of translating
i18nize cs --only_blank
This scans all keys in the source locale (default en) and, for any missing or blank value in the target locale, inserts a placeholder:
<locale>.<full.dot.key> missing
Example:
en:
test:
title: "Testing"
cs:
test:
title: "cs.test.title missing"
Existing non-blank values in the target are left untouched.
🛡️ Character limit check
Before translating, the CLI:
- Counts the total number of characters
- Warns if the count exceeds 500,000 (DeepL Free monthly limit)
- Asks for confirmation:
[i18nize] Estimated character count: 43125
Proceed with translation? [y/N]:
🗂️ Locale file support
Files are matched by name:
config/locales/api/en.yml→config/locales/api/cs.ymlconfig/locales/en.devise.yml→config/locales/cs.devise.yml
Missing files are created automatically
If a scalar exists where a nested structure is required, it is overwritten by source locale structure
🧩 Example structure
config/locales/
├── api/
│ └── en.yml
├── errors/
│ ├── en.yml
│ └── cs.yml
After running:
i18nize cs
the gem will create:
config/locales/api/cs.yml
With keys translated from api/en.yml.
📦 Configuration
For now, configuration is via CLI flags and environment variables:
--from LANG(defaulten)--missing [FROM](list missing keys only)--only_blank(fill only blank/missing keys with placeholders, no DeepL)DEEPL_API_KEY(required for translation mode)DEEPL_ENDPOINT(optional, only for Pro)I18NIZE_ALLOW_EMPTY == "1"→ skip empty/whitespace-only values in the source when inserting or translating (i.e., if a source value is""or" "it will be ignored and not propagated to the target)
🔍 TODO
- RSpec test suite
- YAML key sorting / format preservation
- Richer conflict resolution strategies (configurable overwrite / skip)
- Use custom char limit