Reference / CLI
verbatra pseudo
Generate a pseudolocale from your source strings so clipped buttons and unextracted labels stand out, without calling a provider or reading an API key.
Run your app in a language that does not exist. pseudo builds a fake locale from your source strings: every value is accented, lengthened and wrapped in visible markers, so clipped buttons, concatenated sentences and unextracted labels stand out. With --mode bidi it renders every string right to left instead. It constructs no provider, reads no API key and makes no network request, so it works before any key exists.
Synopsis
verbatra pseudo [flags]Examples
# generate en-XA under .verbatra-local/pseudo
verbatra pseudo
# render every string right to left in ar-XB
verbatra pseudo --mode bidi
# write it where the dev server already serves static files (do not commit a bidi file: GitHub flags its hidden Unicode)
verbatra pseudo --out public/locales-pseudo
# machine-readable result for a script
verbatra pseudo --jsonFlags
| Flag | Argument | Default | Effect |
|---|---|---|---|
--mode | <mode> | accented | the transform: accented or bidi, which renders every word right to left (INVALID_ otherwise) |
--locale | <code> | en-XA (ar-XB with --mode bidi) | the pseudolocale to generate; letters, digits and hyphens only (INVALID_ otherwise) |
--out | <path> | .verbatra-local/pseudo | directory to write the pseudolocale under, relative to the working directory and inside the project root; an empty value is INVALID_ |
Also takes the global flags --cwd, --config and --json.
Behavior
What the transform does
| Step | What you see |
|---|---|
| Accent | every ASCII letter becomes an accented look-alike, so Save reads Śáṽé |
| Expand | the value grows by about a third of its translatable length, roughly what German needs over English |
| Mark | the value is wrapped in [ and ], so a clipped or concatenated string is obvious |
Hello {{name}}, you have {{count}} unread messages becomes
[Ĥéĺĺó {{name}}, ýóú ĥáṽé {{count}} úńŕéáḋ ṁéśśáġéś············].
Only translatable text changes. Placeholders survive in every syntax the format adapters recognise, and inside an ICU message the argument names, plural and select keywords and branch selectors stay as written. vue-i18n pipe-separated plural forms are transformed one by one: car | cars becomes [ćáŕ··] | [ćáŕś··]. The transform is deterministic, so the file diffs cleanly.
Right-to-left mode
--mode bidi replaces the accents with a right-to-left override, the approach Android and Chromium take for their ar-XB pseudolocale, so layout that assumes left-to-right text shows up before any right-to-left translation exists.
| Step | What you see |
|---|---|
| Override | every word is wrapped in a right-to-left mark and override (U+200F U+202E before, U+202C U+200F after), so Save renders as evaS |
| Keep | placeholders, ICU syntax, markup, digits and punctuation stay outside the override and read left to right, as they do in real right-to-left text |
Nothing is accented, lengthened or bracketed: width is what the default mode tests. The file keeps the letters in their stored order, and every value passes the same integrity gate, so placeholders and plural arms stay byte-identical.
The pseudolocale defaults to ar-XB, which Intl.Locale and most i18n libraries resolve to right to left, so an app that derives dir from the locale flips on its own. ar-XB follows Arabic plural rules (zero, one, two, few, many, other). ICU messages, Android <plurals>, gettext, Apple catalogs and vue-i18n pipes resolve a count against the forms the file already has. i18next-json keeps each form under its own _ or _ key, so the file also gets every category the source lacks (_, _, _, _, and ordinal forms the same way), filled from the source's other form, and no count falls back to your fallback language. Pass --locale en-XB to keep English plural rules, and set dir="rtl" yourself.
A sanitiser that strips Unicode format characters removes the override, and the string renders left to right again. Editors and code scanners that warn about hidden bidirectional characters flag the file, one more reason it stays under .verbatra-local.
Nothing broken ever reaches the file
Every generated value passes the same integrity gate as a provider's translation: same placeholders as the source, valid message syntax, not degenerate, not blank. A value that would fail is copied from the source verbatim and named under copied verbatim; that is a report, not a failure.
Where the output goes
The pseudolocale is written outside your real locale files, under .verbatra-local/pseudo by default, which verbatra init adds to .gitignore (pseudo tops the entry up if it is missing). Your files.pattern is expanded inside that directory, so with locales/{locale}.json the default run writes .verbatra-local/pseudo/locales/en-XA.json. Point your dev server there, or pass --out to write where your build already serves.
PSEUDO_ refuses, before anything is read or written:
- a pseudolocale that names your source locale or a target locale,
- an
--outthat puts the file in the same directory as a configured locale file, - an
--outthat is absolute, climbs out of the project root, or, once symbolic links are resolved, lands outside the project, at its root, or on a file the project depends on.
Because the file sits outside files.pattern, translate never spends on it and check and diff never report it.
Formats written by patching an existing file
xliff and apple-xcstrings writers patch units already in the destination document, so the pseudolocale file is re-copied from your source file on every write, and a key added to the source later still arrives. A copied XLIFF has its target-language rewritten to the pseudolocale.
JSON output
Schema: pseudo-envelope.json validates the whole envelope; Schemas lists the others.
With --json, the envelope carries locale, mode (accented or bidi), path, entries (entries written, including plural forms added in bidi mode), transformed (values that differ from the source), copied (keys copied verbatim) and written (false when the file was already current).
Terminal feedback
The result goes to stdout; the progress line and the next step go to stderr:
verbatra: pseudolocalizing the source... done (0.1s)
verbatra pseudo
en-XA (accented): 118 of 120 entries pseudolocalized
copied verbatim: legal.disclaimer, brand.name
wrote .verbatra-local/pseudo/locales/en-XA.json
next: load .verbatra-local/pseudo/locales/en-XA.json as the en-XA locale in your dev serverA second run over an unchanged source reports unchanged instead of wrote. --quiet drops the stderr lines. See Terminal output.
Exit codes
| Code | Meaning |
|---|---|
0 | the pseudolocale was generated, whether or not the file changed; values copied verbatim do not change this |
2 | could not run: a usage error, a config or source problem, or a refused pseudolocale or output path |
Related
verbatra translatedoes the real thing, once you have a key.verbatra doctoralso validates a project without spending anything.- Formats lists the placeholder syntax of each format.
- The config file documents
files.pattern, which sets the generated file's layout.