Docs / Guides
Hand off with Excel or CSV
Export untranslated strings to an Excel workbook or CSV files for a translator, then import the result with the same safety checks as an automated run.
Use this when a person should translate some strings: marketing copy, legal text, or the languages that matter most. You export the strings that need translating, a translator fills them in, and you import the file back into your locale files.
Export picks exactly the keys an automated run would translate (the new and changed ones), and import runs the same integrity checks as translate, so a hand-typed value that breaks a placeholder is withheld and reported instead of written. Neither command calls a provider or needs an API key.
You need a verbatra project with at least one target locale.
The round-trip
# 1. Export the strings that need translating
verbatra export
# 2. A translator fills the Translation column and sends the file back
# 3. Import the filled workbook
verbatra import verbatra-translations.xlsxExport writes verbatra-translations.xlsx in the working directory. Import validates every filled row, writes the values that pass, and advances the lock file for exactly the keys it accepted, as a translate run would.
What lands in the workbook
The workbook opens with an Instructions sheet, then one sheet per target locale, named for its locale (de, fr, ...). Every locale sheet has the same columns:
| Column | Editable | Purpose |
|---|---|---|
Key | no | the key path; the only thing that maps a row back to a string |
Source | no | the source-locale value |
Current translation | no | the existing target value, if any |
Status | no | new, changed (the source changed since it was translated), or unchanged (only with --include-unchanged) |
Translation | yes | the only cell the translator fills |
Source hash | no | hidden; detects a source that changed after export |
Context | no | the key's description, when the source format carries one; never imported |
Review status | no | ok, or review when a review flag suggests a second look |
Review reasons | no | the review reasons behind a review status |
Every column except Translation is locked by sheet protection, and Translation uses Excel's text format, so a value like 007 or one starting with = stays literal text. The review columns are advisory: import never reads them.
Handing off
Tell the translator these rules (the Instructions sheet repeats them):
- Fill the
Translationcolumn, nothing else. - Do not rename, delete or reorder the language tabs. Each tab is matched to a locale by its exact name, so a renamed or missing tab fails that locale.
- Sorting and filtering rows is fine, because rows are matched by
Key. Columns must stay where they are. - Leave a cell empty for "not translated yet". A half-filled workbook can come back now and the rest later.
- To clear an existing value on purpose, type exactly
[[CLEAR]].
What import accepts
Every filled row is judged against the live project before anything is written:
- Source drift: if the source string changed after export, the row is withheld, so a translation of an old source never lands.
- Integrity: placeholders, inline markup and ICU structure must match the source, as in every run. See the integrity gate.
- Degenerate values: a repetition loop, a runaway length or an empty value for a non-empty source is withheld.
- Unknown keys: a filled row whose key exists in neither the source nor the target fails that locale's sheet. A key that exists only in the target is left unwritten.
- Unchanged rows (from 0.13.0): in a CSV, TSV or xlsx handoff, a filled row equal to the value an up-to-date key already holds is left alone and reported unchanged, once it passes the same gate.
A withheld or blank row keeps its lock baseline, so the key is exported again until it is resolved; a blank row whose source drifted also raises BLANK_. An unreadable row or a repeated key is reported without failing the sheet. Each sheet is one locale in the run summary, and import uses the same exit codes as translate, so a handoff fits the same CI checks as an automated run. verbatra import has the details.
Dry-run first
Preview what a returned workbook would write, without touching a file:
verbatra import verbatra-translations.xlsx --dry-runCSV and TSV instead of a workbook
If a vendor or a pipeline wants plain text, --format csv or --format tsv writes the same columns as one file per locale:
# write handoff/de.csv and handoff/fr.csv
verbatra export --format csv --out handoff
# import every locale file in the directory back
verbatra import handoff --format csvThe locale comes from the file name, so keep the files named as they were exported. Compared with the workbook:
- Nothing is protected. Every column is editable and
Source hashis visible. An edited hash is never trusted: the row is compared with the live source and withheld as drift. - There is no Instructions sheet. Pass the rules above to the translator yourself.
- Formulas are defused. A value starting with
=,+,-,@, a tab or a carriage return is written with a leading apostrophe, so a spreadsheet keeps it as text; import strips the apostrophe again. Still treat a returned file as untrusted input. - A narrower re-export retires older files. A file left over from an earlier, wider export is refused on import instead of applied. Nothing is deleted.
XLIFF for a CAT tool
If an agency works in a CAT tool such as Trados, memoQ or OmegaT, export XLIFF instead: see Hand off to an agency.
TMX is a different path
A handoff carries the pending strings of each locale to a person. verbatra tmx moves the whole translation memory between tools as one multilingual file, so it is not an export --format value.
Selecting what to export
By default, export includes only the missing and changed strings:
# Only the German and French sheets
verbatra export --locales de,fr
# Also include strings that are already up to date
verbatra export --include-unchanged
# Write to a specific path
verbatra export --out handoff/round-2.xlsxUse --include-unchanged when a translator wants a whole locale for context. --out must stay inside the project and must not name a file the project depends on. See verbatra export for every flag and rule.
The review columns
Both columns are computed at export from the source and current values, so a row without a translation is always ok. Review reasons spells each reason in lower case with hyphens (length-ratio-outlier), except the two only a run can see (provider-degraded, fuzzy-cache-reuse), which never appear. It adds icu-arms with the missing or extra arms when a value's ICU arms do not fit the target language; the integrity gate refuses that value, so fix it before the row comes back. To clear a flag, fix the translation.
From the SDK
The two commands wrap exportWorkbook and importWorkbook:
import { exportWorkbook, importWorkbook, loadConfig } from "@verbatra/sdk";
const config = await loadConfig();
await exportWorkbook({ config, format: "csv", out: "handoff" });
const summary = await importWorkbook({ config, workbook: "handoff", format: "csv" });importWorkbook returns the same RunSummary as translate.
Related
verbatra exportandverbatra import: every flag, the output paths and the exit codes.- Translation safety: the integrity gate behind every write.
- Run without machine translation: a project where every translation comes from a person.