Docs / Guides
Hand off to an agency (XLIFF)
Export the strings that need translating as XLIFF 2.0 or 1.2 for a CAT tool, and import the returned file through the same safety checks as any run.
Use this when professional translators work in a CAT tool such as Trados, memoQ, OmegaT, Matecat or Phrase. XLIFF reaches them as segments with states, notes and protected placeholders, which is what their translation memory and QA checks are built around. verbatra writes XLIFF from any project format, not only from an XLIFF project, and reads it back through the same import as a workbook handoff.
The round-trip
# 1. Export one XLIFF 2.0 file per target locale into handoff/
verbatra export --format xliff2 --out handoff
# 2. The agency translates handoff/de.xlf, handoff/fr.xlf ... in its CAT tool and sends them back
# 3. Import every returned file, recording who signed off on the reviewed ones
verbatra import handoff --format xliff2 --reviewer "Agency GmbH"If the tool does not read XLIFF 2.0 yet, use --format xliff12. Either way you get one <locale>.xlf per target locale. A file left over from an earlier, wider export is refused on import instead of applied.
To import a single returned file, name it. A path ending in .xlf or .xliff is read as XLIFF without --format, and the XLIFF version comes from the file itself:
verbatra import handoff/de.xlfThe locale comes from the file name. If the tool renamed the file (say to project_), the target language the file declares is matched against your configured locales instead.
What lands in the file
Export picks the same keys as a workbook export: the missing and changed ones, plus the up-to-date ones with --include-unchanged. Each key becomes one unit:
- The key names the unit: the unit's
namein XLIFF 2.0, thetrans-unitidandresnamein XLIFF 1.2. - Placeholders, inline markup and ICU syntax become inline codes (
<ph>), which a CAT tool shows as tags the translator places but cannot edit. The text inside each ICU arm stays translatable. Import turns every code back into its exact original text. - Context travels as notes: a key's description and meaning, where the project format carries them.
- The source hash travels as metadata, so import can tell whether the source changed since export.
- A changed key carries its old translation as the target, as a starting point, in the initial state.
Segment states
The state of each segment comes from the lock file and the key's review decision:
| The key is | XLIFF 2.0 state | XLIFF 1.2 state |
|---|---|---|
| missing | initial, no target | no target |
| stale (source changed) | initial, old translation as target | needs-translation, old translation as target |
| up to date, not reviewed | translated | translated |
| up to date and approved | reviewed | signed-off, and approved="yes" |
| up to date but rejected | initial | needs-translation |
Where a value came from does not change its state: a machine translation, a memory hit and a value a person typed are all translated until someone approves them.
Machine-translation markers
The origin travels next to the state, so the agency can see which targets a machine wrote. In XLIFF 1.2, an unapproved machine-written target carries state-qualifier="mt-suggestion"; in XLIFF 2.0 the unit's metadata carries its origin and review state. Import ignores both. See Record machine-translation evidence.
What import accepts
Every returned unit runs through the checks of a workbook import: the integrity gate, the stale-source guard, [[CLEAR]] to empty a value on purpose, and an empty target meaning "not translated yet". XLIFF adds these rules:
- A target left as exported changes nothing. The key stays byte-identical and keeps its provenance. If you want a stale key's old translation kept for the new source, the translator moves its state past
initial. - Any other target is a translation, whatever its state, because some tools write the text but leave the state alone.
reviewedandfinalrecord an approval. So dosigned-off,finalandapproved="yes"in XLIFF 1.2. The approval is saved inverbatra.provenance.jsonwith the--reviewername and reported asHANDOFF_. An imported value gets the originREVIEWS_ RECORDED import; a value the translator only confirmed keeps its origin, such asmachine.- A stripped source hash falls back to the source text. If the unit's source still matches, it imports; if not, it is withheld as drift.
- Damage is reported, not fatal. A unit with an unknown key or broken inline codes is reported as a malformed row, and a repeated key as a duplicate; the rest of the file still imports.
- The XML is parsed safely. A file that declares an entity or an internal DTD subset is refused, and so is a file larger than 32 MB.
Run verbatra import --dry-run first to see all of this, including the approvals, without writing a file.
XLIFF 1.2 cannot carry a character XML 1.0 forbids (a control character such as U+0007), so such a character is dropped from a 1.2 export. XLIFF 2.0 carries it exactly, so prefer xliff2 when the tool reads it.
Checking a tool by hand: OmegaT
The automated tests edit exported files the way a CAT tool does, but they do not run one. To try a real round-trip, use OmegaT, which is free:
- Export a handoff:
verbatra export --format xliff12 --out handoff(orxliff2). - In OmegaT, create a project with your source and target language, and copy
handoff/de.xlfinto the project'ssourcefolder. - Open the project. Placeholders such as
{{name}}show as tags: translate the text around them, and insert each tag with Ctrl+T (Cmd+T on macOS) instead of typing it. - Translate some segments, leave some untranslated, and save.
- Choose Project, Create Translated Documents. OmegaT writes
de.xlfinto the project'stargetfolder. - Check it:
verbatra import path/to/target/de.xlf --dry-run. Translated segments are listed undertranslated, untouched ones underunfilled, and nothing is refused unless a tag was lost. - Import it:
verbatra import path/to/target/de.xlf, thenverbatra check.
From the SDK
The CLI wraps the same exportWorkbook and importWorkbook as the workbook handoff:
import { exportWorkbook, importWorkbook, loadConfig } from "@verbatra/sdk";
const config = await loadConfig();
await exportWorkbook({ config, format: "xliff2", out: "handoff" });
const summary = await importWorkbook({
config,
workbook: "handoff",
format: "xliff2",
reviewer: "Agency GmbH",
});Related
verbatra export: every export flag, including the XLIFF formats.verbatra import: every import flag, including--reviewer.- Hand off with Excel or CSV: the workbook handoff and every check import applies.