| name | check-i18n |
| description | Validate and auto-fix i18n translation files by detecting hardcoded strings in HTML/JS, ensuring all keys exist, and removing unused translations. Use when working with internationalization, adding UI text, or maintaining translation consistency across web projects. Supports data-i18n attributes and t() function calls. |
Check i18n Translations
Automatically validate, detect, and fix internationalization (i18n) issues in web projects. This skill:
- Validates that all translation keys used in code exist in translations.json
- Detects hardcoded strings in HTML/JS that should be translated
- Auto-fixes by moving hardcoded strings to translations.json and generating translation keys
- Cleans up unused translation keys
When to Use This Skill
- Adding new UI text and ensuring it's translatable
- Refactoring hardcoded strings to use i18n
- Maintaining translation file consistency
- CI/CD validation of translation completeness
- Cleaning up unused translation keys after refactoring
Prerequisites
- Translation file in JSON format (default:
translations.json)
- HTML files using
data-i18n, data-i18n-title, or data-i18n-placeholder attributes
- JavaScript files using
t('key') function for translations
- Python 3.8+ (uses pathlib, re, json)
How It Works
Pattern Detection
HTML attributes:
<button data-i18n-title="editor_save">Save</button>
<span data-i18n="status_ready">Ready</span>
JavaScript function calls:
setStatus(t('editor_loading'));
Hardcoded strings (detected):
<button title="Save">Save</button>
Translation File Structure
Supports both flat and nested structures:
Flat (single language):
{
"editor_title": "Markdown Editor",
"editor_save": "Save"
}
Nested (multi-language):
{
"en": {
"editor_title": "Markdown Editor"
},
"ru": {
"editor_title": "ะ ะตะดะฐะบัะพั Markdown"
}
}
Step-by-Step Workflows
Workflow 1: Validate Existing Translations
When: Running in CI/CD or before committing changes
python scripts/check_i18n.py translations.json
python scripts/check_i18n.py translations.json --html-glob "src/**/*.html" --js-glob "src/**/*.js"
What it checks:
- โ
JSON syntax validity
- โ
All keys used in code exist in translations
- โ ๏ธ Unused keys defined but not referenced
- โ Missing keys referenced but not defined
Workflow 2: Auto-Fix Hardcoded Strings
When: Refactoring UI code to add i18n support
python scripts/check_i18n.py translations.json --auto-fix
python scripts/check_i18n.py translations.json --auto-fix --dry-run
What it does:
- Scans HTML for hardcoded
title= attributes
- Generates translation keys (e.g.,
button_save, tooltip_close)
- Adds keys to translations.json
- Replaces hardcoded strings with
data-i18n-title="generated_key"
Workflow 3: Remove Unused Keys
When: Cleaning up after removing features or refactoring
python scripts/check_i18n.py translations.json --remove-unused
python scripts/check_i18n.py translations.json --remove-unused --interactive
Workflow 4: Makefile Integration
Add to your project's Makefile:
check-i18n: ## Validate translation files
@python scripts/check_i18n.py translations.json
@echo "โ i18n check complete"
fix-i18n: ## Auto-fix hardcoded strings
@python scripts/check_i18n.py translations.json --auto-fix --remove-unused
Configuration
Custom Glob Patterns
Override default search patterns:
[tool.check-i18n]
translations_file = "src/locales/en.json"
html_glob = "templates/**/*.html"
js_glob = "static/js/**/*.js"
key_prefix = "app_"
Key Generation Rules
Auto-generated keys follow this pattern:
{context}_{description}
Examples:
title="Save" โ button_save
title="Close editor" โ editor_close
placeholder="Search..." โ input_search
Troubleshooting
Issue: "No HTML/JS files found"
Cause: Glob pattern doesn't match your project structure
Solution: Specify custom patterns:
python scripts/check_i18n.py translations.json \
--html-glob "frontend/**/*.html" \
--js-glob "frontend/**/*.js"
Issue: "Too many auto-generated keys"
Cause: Script detecting strings that shouldn't be translated (e.g., technical identifiers)
Solution: Add to ignore list:
IGNORE_PATTERNS = [
r'^\d+$',
r'^[A-Z_]+$',
r'^https?://',
]
Issue: "False positive unused keys"
Cause: Keys used dynamically (e.g., t(variableName))
Solution: Mark keys as external:
{
"_external_keys": ["dynamic_key_1", "dynamic_key_2"],
"editor_title": "Editor"
}
Integration with CI/CD
GitHub Actions
name: i18n Validation
on: [pull_request]
jobs:
check-i18n:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- run: python scripts/check_i18n.py translations.json
Pre-commit Hook
repos:
- repo: local
hooks:
- id: check-i18n
name: Validate translations
entry: python scripts/check_i18n.py
args: [translations.json]
language: system
References
- Script:
scripts/check_i18n.py (bundled)
- Example translations:
references/example_translations.json
- Test fixtures:
references/test_cases.md