#I18n Plugin
Find dead translation keys before they pile up. The i18n plugin statically scans your project for $dictionary(...) declarations and reports every key that is never referenced anywhere in the source tree.
#Quick Start
Register the plugin in alepha.config.ts with the i18n() helper:
1import { defineConfig } from "alepha/cli/config";2import { i18n } from "alepha/cli/i18n";3 4export default defineConfig({5 plugins: [i18n()],6});
alepha i18n check
Checked 412 keys across 187 files (3 dictionary files).
✗ Unused translations (2):
- profile.legacy.title
- profile.legacy.subtitle
#What It Does
The check extracts every key declared in your $dictionary(...) calls, then looks for a quoted-literal reference to each key anywhere else in the scanned files. Keys with no reference are reported and the command exits non-zero — wire it into your verify pipeline so removing a feature can't silently strand its translations.
If no translation keys are found at all, the command exits with code 2 and a warning — that usually means the dictionary location changed and the scan is looking in the wrong place.
#Configuration
i18n() accepts the following options:
| Option | Type | Default | Description |
|---|---|---|---|
scan |
string[] |
["src"] |
Directories (relative to the project root) to scan for dictionaries and key usage |
dynamicPrefixes |
string[] |
[] |
Key prefixes constructed at runtime — exempted from the check |
exclude |
string[] |
[] |
Extra path substrings to exclude, on top of the defaults (node_modules, dist, __tests__, .spec.*, .test.*, .alepha) |
1import { defineConfig } from "alepha/cli/config"; 2import { i18n } from "alepha/cli/i18n"; 3 4export default defineConfig({ 5 plugins: [ 6 i18n({ 7 scan: ["src", ".vendor/@alepha/ui"], 8 dynamicPrefixes: ["archive.type.", "petitions.filter."], 9 }),10 ],11});
#Dynamic Keys
A key built with a template literal has no quoted-literal reference:
1tr(`archive.type.${kind}`)
The static scan can't see it, so every archive.type.* key would be reported as unused. Add the prefix to dynamicPrefixes to exempt them.
Audit your prefixes
Keep the
dynamicPrefixeslist short and re-check it when a feature is removed — a stale prefix is a place where dead keys can hide.
#In the Verify Pipeline
Add a check:i18n script to your app and let CI run it:
1{2 "scripts": {3 "check:i18n": "alepha i18n check"4 }5}
The exit codes make it CI-friendly: 0 all keys referenced, 1 unused keys found, 2 no keys found at all.