---
title: "verbatra pseudo"
description: "Generate a pseudolocale from your source strings so clipped buttons and unextracted labels stand out, without calling a provider or reading an API key."
type: "reference"
---
# 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.

<AvailableFrom version="0.11.0" />

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 [#synopsis]

```bash
verbatra pseudo [flags]
```

## Examples [#examples]

```bash
# 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 --json
```

## Flags [#flags]

| Flag | Argument | Default | Effect |
| --- | --- | --- | --- |
| `--mode` | `<mode>` | `accented` | <AvailableFrom version="0.12.0" /> the transform: `accented` or `bidi`, which renders every word right to left (`INVALID_OPTION` otherwise) |
| `--locale` | `<code>` | `en-XA` (`ar-XB` with `--mode bidi`) | the pseudolocale to generate; letters, digits and hyphens only (`INVALID_LOCALE` 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_OUT` |

Also takes the [global flags](https://verbatra.kreitz-webdev.de/docs/cli.md#global-flags) `--cwd`, `--config` and `--json`.

## Behavior [#behavior]

### What the transform does [#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](https://verbatra.kreitz-webdev.de/docs/formats.md) 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 [#right-to-left-mode]

<AvailableFrom version="0.12.0" />

`--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 `_one` or `_other` key, so the file also gets every category the source lacks (`_zero`, `_two`, `_few`, `_many`, 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 [#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 [#where-the-output-goes]

The pseudolocale is written outside your real locale files, under `.verbatra-local/pseudo` by default, which [`verbatra init`](https://verbatra.kreitz-webdev.de/docs/cli/init.md) 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_OUTPUT_CONFLICT` refuses, before anything is read or written:

- a pseudolocale that names your source locale or a target locale,
- an `--out` that puts the file in the same directory as a configured locale file,
- an `--out` that 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`](https://verbatra.kreitz-webdev.de/docs/cli/translate.md) never spends on it and [`check`](https://verbatra.kreitz-webdev.de/docs/cli/check.md) and [`diff`](https://verbatra.kreitz-webdev.de/docs/cli/diff.md) never report it.

### Formats written by patching an existing file [#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 [#json-output]

Schema: [`pseudo-envelope.json`](https://verbatra.kreitz-webdev.de/schema/v1/pseudo-envelope.json) validates the whole envelope; [Schemas](https://verbatra.kreitz-webdev.de/docs/cli/output.md#schemas) lists the others.

With `--json`, the [envelope](https://verbatra.kreitz-webdev.de/docs/cli/output.md#json-output) 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 [#terminal-feedback]

<AvailableFrom version="0.12.0" />

The result goes to stdout; the progress line and the next step go to stderr:

```text output
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 server
```

A second run over an unchanged source reports `unchanged` instead of `wrote`. `--quiet` drops the stderr lines. See [Terminal output](https://verbatra.kreitz-webdev.de/docs/cli/output.md#terminal-output).

## Exit codes [#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 |

See [the exit-code contract](https://verbatra.kreitz-webdev.de/docs/cli/output.md#exit-codes).

## Related [#related]

- [`verbatra translate`](https://verbatra.kreitz-webdev.de/docs/cli/translate.md) does the real thing, once you have a key.
- [`verbatra doctor`](https://verbatra.kreitz-webdev.de/docs/cli/doctor.md) also validates a project without spending anything.
- [Formats](https://verbatra.kreitz-webdev.de/docs/formats.md) lists the placeholder syntax of each format.
- [The config file](https://verbatra.kreitz-webdev.de/docs/config-file.md) documents `files.pattern`, which sets the generated file's layout.
