Skip to content

Deduplication ​

Big projects accumulate duplicate strings: cta.save, button.save, and form.save_button all reading "Save changes". Every duplicate is a string you pay to translate again — and a chance for the copies to drift apart.

openlocale attacks this at import time, where duplicates usually enter.

How matching works ​

During import analysis, each new key's value is checked against the project's existing translations in that locale, in three passes:

  1. Exact — SHA-256 value lookup. Instant at any project size.
  2. Normalized — values are Unicode-normalized, lowercased, whitespace- collapsed, stripped of terminal punctuation, and their placeholder syntax canonicalized, then compared. This catches Save changes. vs save changes, and Hello vs Hello %s — different placeholder dialects, same string.
  3. Fuzzy — character-trigram similarity (≥ 0.85) with length-band pruning, in pure portable code (identical behavior on SQLite and Postgres). Skipped automatically above 20k existing strings to keep imports fast; exact and normalized matching always run.

With an AI license, a fourth semantic pass sends sub-threshold near-misses to the language model, which judges whether the pair genuinely means the same thing — catching rewordings that no string metric can.

The review flow ​

Matches become suggestions on the import review screen, showing the incoming key/value next to the matched existing key/value with the match type and score. For each one you choose:

ActionEffect
Reuse existing keyThe incoming key isn't created; its translations attach to the matched key. Use when the new key is simply redundant.
Link as aliasAn alias record maps the incoming key name → the canonical key. Exports and CDN bundles resolve the alias, so client code using the old name keeps working while you maintain one string.
Create anywayIt's a genuine coincidence — proceed as a new key.

Decisions apply when you commit; unresolved suggestions default to create anyway.

In CI ​

openlocale push --dry-run prints the analysis, lists any duplicate suggestions, and exits with code 2 if there are any — so a pull request that introduces a duplicate string fails its pipeline and gets reviewed before the duplicate ships.

MIT licensed core. AI features unlock with a license key.