---
title: "verbatra export"
description: "Export untranslated strings into a translator handoff, as a styled Excel workbook, one CSV or TSV file per locale, or one XLIFF file per locale for a CAT tool."
type: "reference"
---
# verbatra export

Export untranslated strings into a translator handoff, as a styled Excel workbook, one CSV or TSV file per locale, or one XLIFF file per locale for a CAT tool.

Write the strings that need translating into a handoff a person fills in and sends back for [`verbatra import`](https://verbatra.kreitz-webdev.de/docs/cli/import.md). By default it carries only the missing and changed strings, the same keys an automated run would send to a provider. A key whose source value is empty or whitespace only gets no row until you write its source text. `export` never calls a provider and needs no API key.

## Synopsis [#synopsis]

```bash
verbatra export [flags]
```

## Examples [#examples]

```bash
# write the workbook with missing and changed strings
verbatra export

# only the German and French sheets, to a specific path
verbatra export --locales de,fr --out handoff/round-2.xlsx

# one de.csv and fr.csv under handoff/
verbatra export --format csv --out handoff

# one de.xlf and fr.xlf in XLIFF 2.0 for a CAT tool
verbatra export --format xliff2 --out handoff
```

## Flags [#flags]

| Flag | Argument | Default | Effect |
| --- | --- | --- | --- |
| `--out` | `<path>` | `verbatra-translations.xlsx`, or `verbatra-translations` for the other formats | where to write the handoff: a file for `xlsx`, a directory for `csv`, `tsv`, `xliff2` and `xliff12` |
| `--format` | `<format>` | `xlsx` | `xlsx` (Excel workbook), `csv` or `tsv` (one file per locale), `xliff2` or `xliff12` (one XLIFF file per locale) |
| `--locales` | `<list>` | every configured target locale | export only this comma-separated subset; an unconfigured locale fails with `UNKNOWN_LOCALE` and an empty list with `INVALID_LOCALES`, both exit `2` |
| `--include-unchanged` | none | off | also export strings that are already up to date |

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

## Behavior [#behavior]

### CSV and TSV [#csv-and-tsv]

`--format csv` and `--format tsv` write one `<locale>.csv` or `<locale>.tsv` per exported locale, with the same columns in the same order as a workbook sheet. `--out` names the directory, which is created if it is missing.

A delimited file is diffable and opens anywhere, but it has no cell protection: every column is editable and the `Source hash` column is visible. An edited hash is never trusted: import compares it against the live source and withholds the row.

Each delimited export also writes a hidden manifest, `.verbatra-export-csv.json` or `.verbatra-export-tsv.json`, naming the locales it wrote. A later export with a narrower `--locales` retires the locales it dropped: their files stay on disk, and [`verbatra import`](https://verbatra.kreitz-webdev.de/docs/cli/import.md) refuses them as leftovers. The export never deletes anything from the output directory.

### XLIFF [#xliff]

<AvailableFrom version="0.12.0" />

`--format xliff2` writes XLIFF 2.0 and `--format xliff12` XLIFF 1.2: one `<locale>.xlf` per exported locale in the `--out` directory, plus a `.verbatra-export-xliff.json` manifest that works like the CSV one. Each key becomes a unit named by the key, placeholders and markup become protected inline codes, the key's description and meaning become notes, and the segment state follows the lock and review state (`initial` for a missing or stale key, `translated` when up to date, `reviewed` when approved). See [Hand off to a translation agency](https://verbatra.kreitz-webdev.de/docs/translation-agency.md).

Each target also says where it came from. In XLIFF 1.2, a target a provider, the translation memory or an AI agent wrote, and that no person approved, carries `state-qualifier="mt-suggestion"`; in XLIFF 2.0 the unit's `verbatra` metadata group carries `origin` and `review-state`. Import ignores both. When `verbatra.provenance.json` cannot be read, no marker is written and the `--json` result carries `provenanceMarkers: "unavailable"`. See [Machine-translation evidence](https://verbatra.kreitz-webdev.de/docs/provenance-evidence.md#markers-in-exports).

### Where the handoff is written [#where-the-handoff-is-written]

The handoff is only written inside the project root. Before anything is read, `export` refuses with `EXPORT_OUTPUT_CONFLICT` an `--out` that climbs out of the project root, or that (itself or through a file it would write) names a file the project depends on: a configured locale file, the lock file, the provenance file, the translation-memory cache, a config file verbatra searches for, the config the run loaded, or the configured `glossary` file. For `xlsx`, a path that names no file (such as `out/`) or the project root itself is refused too. Names compare case-insensitively, and the checks run again after symbolic links are resolved.

A path that passes can still fail while writing (not writable, something in the way, disk full): the run stops with `EXPORT_UNWRITABLE`, naming the file and the file-system code.

A target locale that cannot name its sheet or file stops the export with `WORKBOOK_INVALID`. An xlsx sheet name must be 1 to 31 characters, must not contain any of `: \ / ? * [ ]`, and must not match `Instructions` or another target locale's sheet name, ignoring case. A `csv`, `tsv` or `xlf` file name must not be empty, `.` or `..`, and must not contain a path separator, a control character, or any of `: * ? " < > |`. The same code covers a workbook that could not be serialized.

### Terminal feedback [#terminal-feedback]

<AvailableFrom version="0.12.0" />

`export` shows one line while it writes, and when there was anything to hand off it names the import that brings the filled file back:

```text output
verbatra: exporting to xlsx... done (0.3s)
next: verbatra import verbatra-translations.xlsx (once your translators have filled it in)
```

When nothing is pending and `--include-unchanged` was not passed, the file has no rows, and the `next:` line suggests the same export with `--include-unchanged` instead, keeping `--format`, `--out`, `--locales`, `--cwd` and `--config`.

These lines go to stderr, and `--quiet` drops them. See [Terminal output](https://verbatra.kreitz-webdev.de/docs/cli/output.md#terminal-output).

### JSON output [#json-output]

Schema: [`export-envelope.json`](https://verbatra.kreitz-webdev.de/schema/v1/export-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 where the handoff went and the row count per locale:

```ts
{
  path: string;                // absolute path: the workbook for xlsx, the output directory otherwise
  locales: { locale: string; rows: number }[];
  provenanceMarkers?: "written" | "unavailable"; // XLIFF formats only
}
```

## Exit codes [#exit-codes]

| Code | Meaning |
| --- | --- |
| `0` | the handoff was written |
| `2` | could not run: a whole-run error, a refused output path (`EXPORT_OUTPUT_CONFLICT`), a handoff that could not be written (`EXPORT_UNWRITABLE`, `WORKBOOK_INVALID`), or a usage error |

`export` has no per-locale failure mode, so it never exits `1`. See [Exit codes](https://verbatra.kreitz-webdev.de/docs/cli/output.md#exit-codes) for the contract every command follows.

## Related [#related]

- [Manual translation](https://verbatra.kreitz-webdev.de/docs/manual-translation.md) covers the workbook layout, the review columns and the full round-trip.
- [Hand off to a translation agency](https://verbatra.kreitz-webdev.de/docs/translation-agency.md) covers the XLIFF handoff for a CAT tool.
- [`verbatra import`](https://verbatra.kreitz-webdev.de/docs/cli/import.md) reads the filled handoff back.
