A translated build is the most expensive place to discover that a button label is hard-coded, that German does not fit the menu, or that a sentence was glued together from three strings. Pseudo-translation moves those discoveries to the start, before a single word has been paid for.
What it is
Microsoft’s localisation methodology describes pseudo-localisation as a way to check that a product can be localised without translating it into a real language. Pseudo-translation is the core of it: the source text is transformed automatically to imitate the effects of translation, while staying readable enough that you can still use and test the product.
So Save changes becomes [!!Sávé cháñgés~~~~!!] in the tool described at the end of
this guide. A tester who reads English can still find the button, and everything the
transformation was designed to expose is now visible on screen.
It finds many problems early, but it does not replace testing the real translated product. Think of it as a cheap first pass, not a sign-off.
What it finds
- Hard-coded strings. Text that stays in plain English after pseudo-localisation was never in the resource files, so it would never have reached translators. Android’s documentation calls this out directly.
- Truncation. Wrapping each string in start and end markers makes clipping obvious: if the closing marker is missing, the text was cut off.
- Concatenation. A sentence assembled from several pieces shows up as several bracketed messages side by side. Translators cannot reorder pieces they receive separately, so this is a bug in the source, not a translation problem.
- Font and encoding problems. Accented letters, and characters from other scripts, reveal fonts that lack them and pipelines that mangle anything outside ASCII.
- Layouts that cannot grow. Padding the text shows which containers stretch and which overflow.
How long should the padding be?
There is no single right number, because expansion depends on string length:
| Source | Guidance |
|---|---|
| Microsoft | Lengthen English source text by about 40% as a rule of thumb, though some real translations come out 200% or even 400% longer. Short strings grow proportionally more. |
| W3C, quoting IBM | From English into European languages: 200–300% for strings up to 10 characters, falling to about 130% for strings over 70 characters (article). |
The often-repeated “German is 30% longer” has no official source behind it. The practical lesson from both tables is that one- and two-word labels are where layouts break, because they can double or triple in length while long sentences grow by a third.
The techniques
Most pseudo-translators combine the same few moves:
- Accented look-alikes. Letters become accented versions of themselves, sometimes characters from other scripts, and digits sometimes become circled digits.
- Expansion. Extra characters are added to simulate longer languages. Microsoft suggests padding with characters from scripts such as Greek, Cyrillic, Asian and Indic scripts to surface clipping and font problems at the same time.
- Markers. A fixed start and end marker around every string, for truncation and concatenation.
- Mirroring. For right-to-left testing, the text direction is flipped so you can check a mirrored layout without knowing a right-to-left language.
Pseudo-locales built into platforms
Two platforms ship pseudo-locales you can switch on without translating anything:
- Android has English (XA), which adds accents, expands the text with extra
unaccented characters and wraps each message in brackets, and AR (XB), which switches
text to right-to-left. They need Android 4.3 (API level 18) or later with developer
options on, and are enabled per build with
pseudoLocalesEnabledin Gradle. The locale codes are usually writtenen-XAandar-XB; Android’s own page only names them English (XA) and AR (XB), and the full codes come from a Unicode CLDR ticket. - Windows defines three pseudo-locales:
qps-ploc(base),qps-plocm(mirrored, right-to-left) andqps-ploca(East Asian). Theqpsnames come from the range of language codes reserved for private use, so they can never collide with a real language (Microsoft).
Pseudo-translating a bilingual file
Platform pseudo-locales work on a running app. If your strings travel as XLIFF, PO or a spreadsheet, you can pseudo-translate the file itself and run it through your normal import, which also tests the round trip. The pseudo-translate tool does this in the browser, with nothing uploaded. Per segment it writes:
"[!!" + the source with a, e, i, o, u and n accented + "~" padding of 30% + "!!]"
The padding is 30% of the segment’s translatable characters, spaces included, rounded up; placeholders and tags do not count, because a real translator would not make them longer either.
The details matter more than the decoration:
- Placeholders and inline tags are copied through untouched, so the file still
imports. Seven placeholder syntaxes are recognised, the same ones the
placeholder check uses, from
{name}and%1$sto$t()and<0>. The placeholder guide lists them. - Locked segments and empty sources are skipped. Every other segment is rewritten, including ones that already have a translation, and set to draft. Run it on a copy, not on a file you have translated.
- It is deterministic. The same input always gives the same output, so a diff between two runs shows only what changed in the source.
- The output downloads as
name.pseudo.extnext to your original.
Two limits. Its 30% padding sits below Microsoft’s 40% rule of thumb and far below what
short labels can reach, so treat a clean pseudo pass as a floor, not proof that every
label fits. And ICU messages are not protected: in {count, plural, one {…} other {…}}
the keywords would be accented too, which breaks the message. Leave ICU strings out of
a pseudo pass, or check them separately. Spreadsheets and CSV files have no status, so
there the draft marking has nowhere to go.
What to do with the result
Build with the pseudo-translated strings, then walk the product looking for four things: plain English (hard-coded), missing closing markers (truncation), several bracketed fragments in one sentence (concatenation), and boxes or question marks (fonts and encoding). Fix those in the source before you send the strings to translators, and the first translated build will have far fewer surprises.