Your app shows {name} instead of the name
A translated string renders the placeholder literally instead of substituting the value. Why it happens, how to find every instance, and how to fix it.
What you see
- •The UI prints `{name}`, `{{count}}` or `%{names}` as text, in one language only.
- •English is fine. A bug report arrives from a user in another locale, or nobody reports it at all.
- •Tests pass, the locale file is valid, and a key-diffing check finds nothing wrong.
Why it happens
The placeholder in the translation no longer matches the one the code passes. There are three ways that happens, and all three are invisible to a key-set diff: the variable name was translated along with the sentence, the source key was renamed and the translations were not, or the placeholder was simply dropped.
1The variable name got translated
A translator or a model treated the token as prose. `{name}` becomes `{naam}` in Afrikaans, `{名前}` in Japanese, `%{рецепт}` in Russian. The renderer has no variable by that name, so the raw token reaches the user.
Afrikaans `state.connected_to` carried `{naam}` where the source has `{name}`.
2The source renamed the variable
English moved from `{team}` to `{workspace}` and the 30-odd translations kept `{team}`. Key parity is perfect, so a check that only compares key sets passes.
`team.join_team` still read `{team}` in 21 locales after the source switched to `{workspace}` — German `{team} beitreten`, Spanish `Entrar al espacio de trabajo {team}`.
Our report — the Afrikaans fix merged; the other 25 locales are still open →
3The placeholder was dropped
The translation reads as a complete sentence, so nothing looks wrong, but the value it was supposed to name is gone. The user gets a generic message instead of a specific one.
solidusio/solidus5.3k★
Dutch and Polish dropped `%{names}` from the out-of-stock flash, so the message could not say which item became unavailable.
Find every instance
Point the checker at your locale directory. No API key, no account, nothing leaves your machine:
npx @shipi18n/cli@latest check ./locales -s en --severity 'missing-key=off,untranslated=off,orphan-key=off'Those flags narrow the output to placeholder and plural problems. Drop them to see missing and untranslated keys too, which on a partly-translated project is a much longer list.
✗ es coverage 100.0% 1 error(s), 0 warning(s)
error greeting placeholder-missing — dropped {name}How to fix it
- 1Restore the placeholder using the source spelling exactly. The token is an identifier, not prose: it is never translated, even when the surrounding sentence is.
- 2If the source renamed a variable, sweep every locale at once rather than the one that was reported. In our scan the reported locale was almost never the only broken one.
- 3Add the check to CI so the next one fails the pull request instead of shipping. `--baseline` records what exists today and fails only on newly-introduced drift.
The rules that catch this
How often this actually happens
Found in 21 of 64 public repositories we scanned, 119 strings, each read against the source string by hand: https://shipi18n.com/oss