Skip to Content
ArchitectureDecisionsADR 002 — Configurable translation call sites for key extraction

ADR 002 — Configurable translation call sites for key extraction

Status: Accepted

Context

Validate (and any future lint-style features) need to know which function calls represent translation lookups, e.g. t('screen.title'), i18n.t('screen.title'), $t('screen.title'). Real codebases differ in import aliases, namespaces, and wrappers. We had to choose between hard-coding one pattern, regex-only heuristics with no config, or a declarative config that lists acceptable call shapes. The tool therefore needs a configurable story for translation calls (same concept as functions for generate / fill / sync).

Decision rationale

Expose a functions field on the i18nprune config: a list of base callee names the extractor treats as translation functions for string literal first arguments (with optional chaining and simple wrappers as implemented in packages/cli/src/core/extractor/).

Example:

{ "functions": ["t", "i18n.t"] }

The extractor walks the configured patterns; validate then checks that extracted keys exist in the source locale JSON.

The Why

A single global name (t only) breaks most real codebases. Auto-detect from imports would require full program analysis, be slow, and remain brittle. Per-directory override files add merge-order complexity — deferred. Regex-only extraction produces false positives and breaks on formatting. AST extraction + configurable callees balances accuracy and control.

Consequences

Positive: Teams opt in to which helpers count; the same list drives documentation.

Negative: Users must maintain functions when renaming helpers. Dynamic keys remain unsupported by design.

Operational: Defaults cover common cases; extractor changes belong in the changelog and major bumps when behaviour shifts.

See also

  • packages/cli/src/core/extractor/ — literal and template handling
  • Validate command