Finding missing keys, translating in context, handling plural forms correctly
Language files drift apart in every growing project eventually: a new string gets added in the source language, the translation in three other language files gets forgotten, and nobody notices until a customer reports an English placeholder text showing up in the German interface. This article shows how Claude helps systematically find missing keys, produce context-appropriate rather than literal translations, and correctly handle pluralization rules.
Table of Contents
- 1. The core problem: language files drift apart
- 2. Systematically finding missing translation keys
- 3. Context-appropriate rather than literal translation suggestions
- 4. Accounting for pluralization rules across languages
- 5. Handling placeholders and interpolation correctly
- 6. Terminology consistency across the project
- 7. Automated workflow: a CI check for missing keys
- 8. Using Claude as a reviewer for translation quality
- 9. Cultural adaptation beyond pure language translation
- 10. Summary
- 11. FAQ
1. The core problem: language files drift apart
In most projects, text is first written in a source language, often English, and only afterward carried over into further language files. In practice, this process is rarely in sync: a new feature ships, the translation for two of five supported languages is still missing, and without systematic checking that only surfaces once a user sees the missing text as an English fallback or a raw key name.
The problem gets worse with every additional language, since the number of possible gaps grows linearly with the number of language files. A manual diff between files becomes impractical past a few hundred keys, especially since nested JSON or YAML structures easily hide gaps at deeper levels.
2. Systematically finding missing translation keys
Claude is well suited to designing a script that recursively reads all language files, treats the key structure of the reference language as a baseline, and lists precisely, for every other language, which keys are missing, which exist but shouldn't, and which exist but have an empty or identical value compared to the source language, which often points to a forgotten translation rather than a deliberate match.
Such a script can be wired directly into the CI pipeline, so a pull request that adds new text in the source language gets flagged automatically when the corresponding translations are missing. That shifts the check from a manual, error-prone pass before release to an automated check on every single commit.
import json
from pathlib import Path
def flatten(d: dict, prefix: str = "") -> dict:
result = {}
for key, value in d.items():
full_key = f"{prefix}.{key}" if prefix else key
if isinstance(value, dict):
result.update(flatten(value, full_key))
else:
result[full_key] = value
return result
def find_missing_keys(reference_lang: str, target_langs: list[str], base_dir: Path):
reference = flatten(json.loads((base_dir / f"{reference_lang}.json").read_text()))
report = {}
for lang in target_langs:
target = flatten(json.loads((base_dir / f"{lang}.json").read_text()))
missing = sorted(set(reference) - set(target))
identical = [k for k in target if target.get(k) == reference.get(k) and k in reference]
report[lang] = {"missing": missing, "suspiciously_identical": identical}
return report
3. Context-appropriate rather than literal translation suggestions
A literal translation is frequently the wrong choice for UI text. The German button label Jetzt loslegen becomes a clunky construction when translated word for word into English, while a context-appropriate translation like Get started reads far more naturally in the interface and matches the usual tone of controls. Claude delivers better suggestions when the context is explicitly supplied: is this a button, an error message, a tooltip, or body text.
It is especially valuable to give Claude not just the isolated string but the surrounding usage context, for example a description of the screenshot, the maximum available character width for a button, or the tone of the rest of the interface. That extra information prevents technically correct but interface-inappropriate translations that hit the meaning but fall stylistically out of step.
Prompt for context-appropriate translation:
Translate the following UI strings from German to English for a
B2B SaaS application with a formal tone:
- key: "checkout.error.card_declined"
context: Error message directly under the payment form
source: "Ihre Karte konnte nicht belastet werden. Bitte versuchen
Sie es erneut."
- key: "onboarding.cta.primary"
context: Primary button, max. 20 character width
source: "Jetzt loslegen"
Deliver natural, context-appropriate translations, not literal
word-for-word renderings.
4. Accounting for pluralization rules across languages
English and German only have two plural forms, singular and plural, which tempts many developers into treating pluralization as a simple one-bit problem. Other languages clearly disprove that assumption: Russian needs three distinct forms depending on the last digit of the number, Arabic has up to six forms including dedicated rules for zero, one, and two, and Polish additionally distinguishes between small and large numbers.
Claude knows the CLDR plural rules of common languages and, given an ICU MessageFormat pattern, can reliably fill in all the forms a target language needs, instead of naively copying just the two forms present in the source text. It matters to explicitly ask in the prompt for the ICU standard or whichever pluralization format the project uses, since different frameworks use slightly different syntax.
// ICU MessageFormat, example Russian (3 forms needed)
{
"cart.items_count": "{count, plural, one {# item} other {# items}}"
}
// Correctly resolved by Claude for Russian:
{
"cart.items_count": "{count, plural, one {# товар} few {# товара} many {# товаров} other {# товара}}"
}
// one: 1, 21, 31... / few: 2-4, 22-24... / many: 0, 5-20, 25-30...
5. Handling placeholders and interpolation correctly
A common mistake in automated or semi-automated translation is accidentally altering placeholders, for example {userName} getting translated into {Benutzername}, even though the placeholder in the code must match exactly what the application references. Claude reliably translates around placeholders correctly when the prompt explicitly states that text inside curly or square brackets must remain unchanged.
Word order around placeholders should also be checked, since some languages require a different sentence structure than the source language. A string like {count} new messages from {sender} cannot be sensibly translated into the same order in every language, and Claude can suggest such reorderings as long as the placeholders themselves stay untouched.
6. Terminology consistency across the project
In larger projects with multiple translators or multiple translation rounds spread over months, terminology inconsistency creeps in easily: the same domain term gets rendered with one translation in one place and a second, also correct but different translation elsewhere. To users this reads as inconsistent and hampers comprehension, even when both variants are individually correct.
Claude can align new translation suggestions consistently against a maintained glossary of preferred term translations, and an existing set of language files can be searched specifically for terms translated inconsistently. This consistency check is far faster than a manual review of every string.
7. Automated workflow: a CI check for missing keys
A CI check for missing translation keys should run on every pull request that touches the reference language file, and should fail the pipeline with a warning or, in stricter projects, a hard error, as long as not every target language contains the new key. Claude reliably generates such a check script, including readable output that lists exactly which keys are missing per language.
It is also worth adding automatic assignment: when a translation is missing, a script can automatically generate a translation suggestion from Claude and insert it into the language file marked as a draft, so a human reviewer only needs to check it instead of translating from scratch. That noticeably speeds up the workflow without removing human quality control.
#!/bin/bash
# CI check: fails the build when translation keys are missing
set -euo pipefail
MISSING=$(python3 scripts/find_missing_keys.py \
--reference en \
--targets de,fr,es,it \
--format json | jq '[.[] | .missing] | flatten | length')
if [ "$MISSING" -gt 0 ]; then
echo "Error: $MISSING missing translation keys found."
python3 scripts/find_missing_keys.py --reference en --targets de,fr,es,it
exit 1
fi
echo "All translation keys are complete.
8. Using Claude as a reviewer for translation quality
Beyond producing new translations, Claude also works well as a reviewer for existing, human-translated strings. A review prompt that describes the target audience, the tone, and known terminology guidelines reliably surfaces places where a translation is grammatically correct but stylistically off, too formal, too informal, or inconsistent with the rest of the interface.
This review step does not replace a native-speaker final sign-off for business-critical text, but it substantially reduces the number of problems that ever reach human review in the first place, since obvious inconsistencies and tone breaks get caught and fixed beforehand.
9. Cultural adaptation beyond pure language translation
Internationalization does not end at correct grammar. Date formats, number formats, address conventions, and even color associations differ between target markets, and a technically correct translation can still feel culturally off, for example an informal tone in a market where business communication is traditionally formal.
Claude can help identify such cultural adaptation needs, for example flagging unusual address conventions or phrasing that could read as ambiguous in certain markets, but it does not replace local market expertise for especially sensitive or legally relevant text such as terms of service or cancellation notices.
| Language | Number of plural forms | Example rule | Common translation mistake |
|---|---|---|---|
| German | 2 (singular, plural) | 1 item / 2 items | Literal instead of natural phrasing |
| English | 2 (singular, plural) | 1 item / 2 items | Reference language, rarely wrong |
| Russian | 3 (one, few, many) | 1, 21 / 2-4, 22-24 / 0, 5-20 | Naively copying the two-form structure |
| Arabic | 6 (zero, one, two, few, many, other) | 0 / 1 / 2 / 3-10 / 11-99 / 100+ | Missing dedicated form for dual (two) |
| Polish | 4 (one, few, many, other) | 1 / 2-4 / 5-21 / 22-24 | Confusing it with the Russian rule |
| Japanese | 1 (no plural distinction) | 1 個 / 5 個 identically structured | Unnecessarily building in plural-form logic |
Mironsoft
AI-assisted development, agent workflows, and team processes
Using Claude or other AI tools on the team, but without a clear workflow?
We set up AI-assisted development workflows for teams, from CLAUDE.md conventions to subagent strategies to code review processes that combine human oversight with AI speed.
Workflow Setup
Cleanly set up CLAUDE.md, project conventions, and tool permissions for the team.
Agent Strategy
Build subagent and automation workflows for recurring development tasks.
Team Onboarding
Train developers in productive, safe use of AI coding assistants.
10. Summary
Managing Translation Strings with Claude: The Essentials
Missing keys
Recursive comparison of language files reliably surfaces gaps, ideal for CI.
Context matters
Context-appropriate rather than literal translation needs details about placement.
Plural forms
Many languages need more than two forms, CLDR rules are the standard.
Review role
Claude works as a first-pass check but does not replace native-speaker sign-off.