@another-art/i18n-checker
v0.0.2
Published
Scan i18n translation files for missing keys, extra keys, and placeholder mismatches
Downloads
423
Maintainers
Readme
i18n-checker
Scan i18n translation files for missing keys, extra keys, and placeholder mismatches. Zero dependencies.
Install
npm install @another-art/i18n-checkerCLI
npx @another-art/i18n-checker ./path/to/projectStarts a local server with an interactive UI showing all translation issues.
Options:
PORTenv variable to set port (default:3999, auto-increments if busy)
PORT=4000 npx @another-art/i18n-checker .Library
import { scan, buildHtml } from '@another-art/i18n-checker';
const result = await scan('/path/to/project');
console.log(result.totalMissing); // missing keys count
console.log(result.totalExtra); // extra keys count
console.log(result.totalPlaceholder); // placeholder mismatch count
for (const dir of result.results) {
console.log(dir.i18nPath, dir.issues.length);
for (const issue of dir.issues) {
console.log(` [${issue.type}] ${issue.locale} — ${issue.key}`);
}
}
// Generate HTML report
const html = buildHtml(result);Supported formats
Folder format — i18n/<locale>/index.json:
src/
i18n/
en/
index.json ← { "greeting": "Hello, {name}!" }
ru/
index.json ← { "greeting": "Привет, {name}!" }Flat format — <locale>.json files in the same directory:
locales/
en.json ← { "save": "Save", "cancel": "Cancel" }
ru.json ← { "save": "Сохранить" }Flat format is detected when a directory contains 2+ files matching <locale>.json (2-3 letter codes).
Detected issues
| Type | Description |
|------|-------------|
| missing | Key exists in reference locale but not in target |
| extra | Key exists in target but not in reference locale |
| placeholder_mismatch | Placeholders like {name} differ between locales |
Reference locale is en if present, otherwise the first locale alphabetically.
Types
interface ScanResult {
root: string;
results: CheckResult[];
totalMissing: number;
totalExtra: number;
totalPlaceholder: number;
}
interface CheckResult {
i18nPath: string;
referenceLocale: string;
allLocales: string[];
totalKeys: number;
issues: Issue[];
translations: Record<string, Record<string, string>>;
}
interface Issue {
locale: string;
key: string;
type: 'missing' | 'extra' | 'placeholder_mismatch';
detail?: string;
referenceValue?: string;
localeValue?: string;
}License
MIT
