Skip to content

Docs / Guides

Run without machine translation

Run verbatra with machine translation disabled by policy, so no string ever reaches a translation service and every translation comes from a person.

Available from 0.12.0

Use this when an NDA, a customer contract or a company rule forbids sending strings to any AI or translation service. With the provider set to none, every command that could spend or send anything either works from local data alone or refuses. Everything that needs no provider (diffing, the lock file, the translation memory, export and import, checks, types, pseudolocalization, extraction) works as before.

You need a verbatra project, or a folder where you are about to run verbatra init.

Set it up

verbatra init --provider none

That writes a config whose provider block is just this, and no .env.example, because no API key is ever read:

verbatra.config.ts
provider: { id: "none" }

In an existing project, replace the provider block with { id: "none" }. verbatra doctor then reports "machine translation disabled by policy" and passes its provider and API key checks without looking for a key.

What each command does

CommandWith provider: { id: "none" }
translate, watchfill a key only from an exact translation memory hit, never a fuzzy one; every other missing or changed key is listed as unfilled, left untouched and offered again next run. translate exits 3 while any key is left
export, import, tmxunchanged: the handoff and the translation memory are how human translations get in
check, diff, doctor, pseudo, types, extractunchanged; none of them calls a provider
studio, mcplocal reads and edits work; the provider-spending actions are never offered, even with --allow-spend
SDK retranslateEntryfails with MACHINE_TRANSLATION_DISABLED before it reads or locks anything

No provider is constructed on any of these paths, whatever the environment holds, and no network request is made.

Switching from a machine provider

The translation memory keeps human-only work in a bucket of its own, apart from anything a machine provider produced, so switching to none starts from an empty memory. Changing tone or the glossary never touches that bucket.

If you want to carry earlier translations across, move them explicitly, knowing that you are importing machine output into an otherwise human-only memory. Export before you switch: right after the switch, tmx export writes the human-only bucket, which is still empty.

# 1. Still on the old provider: export its memory
verbatra tmx export

# 2. Switch the config to provider: { id: "none" }

# 3. Import it into the human-only bucket
verbatra tmx import verbatra-memory.tmx

See verbatra tmx for the file name and flags.

The day-to-day loop

# 1. After source strings change, see what needs a human
verbatra translate          # exits 3 and lists the unfilled keys

# 2. Hand them to your translators
verbatra export

# 3. Bring the filled workbook back
verbatra import verbatra-translations.xlsx

# 4. Gate CI on it
verbatra check

Step 1 is optional, because verbatra diff and verbatra check show the same pending keys. It is still worth running: it fills every key the translation memory already covers, so your translators only see what is truly new. For the handoff itself, see Hand off with Excel or CSV or Hand off to an agency.

In CI

translate exits 3 when keys are waiting for a human (exit codes), so a pipeline can fail the build, open a translation request, or just report. The GitHub Action passes the step on exit 3 and sets its needs-human output to "true" for a later step to act on.

Edit on GitHub

On this page