How it works
Your file comes back as your file, not a rebuilt copy of it
This page is for the person who has to decide whether a tool can touch a live job. It explains how xliff.ai writes a file back out, what survives the round trip in each format, how that is tested, and — in its own section — what has not been tested yet.
Only the bytes you changed
The usual way to write a translation file back out is to parse it into a document
tree and serialize the tree. What comes out is a file that is equivalent to the
one you opened, and a serializer is free to normalize as it writes: CDATA can
collapse,   can become a raw
non-breaking space, attribute order and namespace prefixes can change, the byte
order mark can go, and CRLF can become LF. Every one of those is a legal XML
transformation. Every one of them can also be the reason a project manager opens
the file in a vendor tool and it will not load — or worse, loads with the match
rates wrong.
xliff.ai never serializes. It keeps the file you opened exactly as you opened it, and records where each segment's target sits in those bytes. When you export, it re-reads your original file, compares it against what is on screen, and replaces only the byte ranges whose targets actually changed. Everything else is copied across verbatim.
That is why an unedited segment produces no change at all. Byte-identity is not something the code works to achieve — it is what is left when there is nothing to write.
One segment, before and after
<trans-unit id="a1f4c9e0-3b7d-4f21-8c5a-9e0d6b2f7143">
<source>Back up your files automatically.</source>
<seg-source><mrk mtype="seg" mid="1">Back up your files
automatically.</mrk></seg-source>
<target><mrk mtype="seg" mid="1">Dateien automatisch
sichern.</mrk></target>
<sdl:seg-defs>
<sdl:seg id="1" conf="Draft" origin="tm"
percent="74" struct-match="true"/>
</sdl:seg-defs>
</trans-unit> <trans-unit id="a1f4c9e0-3b7d-4f21-8c5a-9e0d6b2f7143">
<source>Back up your files automatically.</source>
<seg-source><mrk mtype="seg" mid="1">Back up your files
automatically.</mrk></seg-source>
<target><mrk mtype="seg" mid="1">Sichern Sie Ihre Dateien
automatisch.</mrk></target>
<sdl:seg-defs>
<sdl:seg id="1" conf="Translated" origin="tm"
percent="74" struct-match="true"/>
</sdl:seg-defs>
</trans-unit>
Two changed ranges. origin,
percent and
struct-match were not written — they are
still the bytes your client sent, on the same line as the attribute that was.
Nothing outside this unit is written at all: not the comment definitions, not the
tag definitions, not the file header.
You can check this without trusting anyone. Open a real job, change nothing, export
it, and compare the two files with a byte diff —
fc /b on Windows,
cmp elsewhere. They are identical, byte order
mark and CRLF line endings included. If a single byte differs, that is a bug and we
want the file.
Two ways to write a file
Parse to a tree, write the tree back
every byte rewritten
What xliff.ai does
two ranges rewritten
What survives a round trip
The rows below are the things a client checks when a file comes back. The columns are the six formats, and every column heading is a page explaining that format.
Scroll the table sideways to see every format.
| XLIFF 1.2 | XLIFF 2.0 | SDLXLIFF | MQXLIFF | XLSX | CSV | |
|---|---|---|---|---|---|---|
| Everything outside a segment you edited | identical | identical | identical | identical | structural | structural |
| Segment status | on change | on change | on change | on change | not applicable | not applicable |
| Match rate and origin | not applicable | not applicable | identical | identical | not applicable | not applicable |
| Comments and notes | identical | identical | identical | identical | not applicable | not applicable |
| Locked segments | read-only | read-only | read-only | read-only | not applicable | not applicable |
| Inline tag definitions | identical | identical | identical | identical | not applicable | not applicable |
| Namespace prefixes, attribute order, entity style, indentation | identical | identical | identical | identical | not applicable | not applicable |
| Encoding, byte order mark, line endings | identical | identical | identical | identical | not applicable | reproduced |
| Sheet and column structure, cell types, formatting | not applicable | not applicable | not applicable | not applicable | preserved | not applicable |
- identical
- These bytes are never written. The export starts from the file you opened and copies them across.
- on change
- Written, and only in the segments whose status you changed. In an SDLXLIFF that is the conf attribute alone; the rest of the same tag is untouched.
- read-only
- Visible, searchable and filterable. There is nothing to write, so nothing can be lost.
- structural
- A spreadsheet is repacked by its own writer, so byte-identity does not apply. Sheet and column structure, row order, cell types and the formatting of cells you did not touch are preserved.
- reproduced
- The delimiter, quote policy, line ending, byte order mark and encoding are detected on open and written back the same way.
Two gates prove it, and a third has not been run
Gate A — an unedited round trip is byte-identical. Parse a fixture, export it with zero edits, assert the output equals the input byte for byte: same length, no differing byte at any offset. It runs over the 19 byte-exact fixtures, and it runs each of them twice — once on the normal path, and once with the parse-time cache deliberately thrown away so the exporter has to re-derive every offset from the original bytes alone. That second run is the path a file takes when your session is restored after a reload, and it is the path nobody exercises by hand.
Gate B — an edit changes only its own byte range. Parse a fixture, replace exactly one segment's target, export, then find the first and last differing bytes between input and output. Both must fall inside that segment's declared target span. Not "the file still parses", and not "the other segments still read the same" — the actual byte range of the change is bounded by the segment you edited.
Together that is 72 assertions over the corpus.
The corpus is 48 hand-authored fixtures, and every one of them is built to be
hostile: UTF-16LE with a byte order mark, UTF-8 with a byte order mark and CRLF and
no trailing newline (which is what Trados actually writes), CDATA-wrapped targets,
processing instructions, comments in the prolog, NFD combining sequences,
right-to-left Arabic, emoji beyond the BMP, self-closing and absent
<target> elements, locked segments,
mixed indentation, and
xml:space="preserve". The byte-sensitive
ones are generated by script rather than typed, because editors and sync clients
silently rewrite byte order marks and line endings.
On top of that, 950 fuzz cases: each of the 19 XML fixtures gets 25 random truncations and 25 random single-byte corruptions. Every one has to produce either a readable error that names the next action, or a document — never a crash, and never an export that invents bytes. Six further fixtures are malformed on purpose and assert the same thing.
What has not been proved
Gates A and B prove that the bytes this editor writes are the bytes it read, everywhere outside the ranges you edited. They do not prove that Trados Studio opens the result without a warning, that memoQ still shows the right match rates, or that Studio's own Verify (F8) passes. That needs the applications, and licences for them, and it has not been done.
So the honest description of SDLXLIFF and MQXLIFF support is this: verified against the format documentation and against byte-level tests, not yet against the vendor applications. If you are deciding whether to run a live job through this, that is the sentence that matters.
Keep a copy of the file you started with, and open the export in the tool that will consume it before you deliver. If it rejects something, write to xliff@terratra.com and say what happened — a file that opens wrong is the most valuable bug report this tool can get.
The rest of the workbench
- Keyboard, not mouse
- Ctrl+Enter confirms the segment and goes to the next unconfirmed one. Ctrl+Insert copies the source, Alt+Delete clears the target, Ctrl+F and Ctrl+H find and replace, F3 runs a concordance search, Ctrl+Z undoes. Ctrl+/ shows the whole table, and switches it to a Trados Studio or memoQ layout: the same commands, moved onto the keys those tools use.
- Repetitions fill themselves
- Confirm a segment and every empty segment with the same source and the same tags is filled with your translation, as a draft, so it stays on the confirm chain for you to read. A translated or confirmed segment is never overwritten, a strip says how many were filled, and one Ctrl+Z takes it all back.
- Fifteen QA checks
- Inline tags, placeholders in seven syntaxes, locale-aware numbers, punctuation with per-language rules, missing no-break spaces, repeated words, capitalization, length, whitespace at the edges, consistency in both directions, and glossary and forbidden terms imported from a TBX, CSV or XLSX. Severity is set per check, and the issues filter the grid. What the QA checks look for
- Inline tags are objects, not text
- A tag chip cannot be split by typing, and deleting one half of a pair either removes both or refuses. Both are property-tested rather than asserted on examples. How inline tags are handled
- A translation memory from your own disk
- Import a TMX 1.4b, a two-column CSV, TSV or XLSX, or a bilingual file you already translated, and pretranslate from it. Exact, context and fuzzy matching, with penalties for case, whitespace, numbers, tags and language variant. A memory stores where a tag stood and never the tag itself, so it cannot carry markup from one file into another. XLIFF to TMX
- Six exports
- The clean file; a review workbook with a real Excel decision dropdown whose decisions import back; TMX with tags stripped or kept; a bilingual XLSX; a QA report as XLSX or CSV; and pseudo-translation. XLIFF to Excel Pseudo-translate
- AI review with your own key
- Anthropic, OpenAI, Gemini, OpenRouter, DeepSeek, Azure OpenAI, or an endpoint you name. This is the one feature that sends text off your machine, and only the segments you select, only when you press the button, and only to the provider you chose. The key stays in this browser, and a session-only mode keeps it out of storage.
- Invisible characters, made visible
- No-break spaces, soft hyphens, zero-width characters and double spaces can be marked in the grid, counted in an audit that separates source from target, and typed on purpose — Ctrl+Shift+Space inserts a no-break space. Nothing is ever cleaned up without a click.
- It runs with the network off
- The editor shell is precached under a content-derived cache name and the site installs as an app. Reload with the network switched off and it still opens your file.
- Your work survives a reload
- Every edit and two hundred steps of undo are written to this browser's own storage as you type, and a hard reload offers the session back. If the browser refuses to store something, a banner says so rather than losing it quietly.
There is nothing to trust, because there is nothing there
There is no upload endpoint. There is no account, no storage quota and no cleanup job, because there is no server to run them on. The site is static files; the parser, the QA engine and the export all run in a worker thread in this tab.
That is not a privacy policy, it is the architecture. You can read it off the network tab: open a file and watch for a request that carries it. There is not one. The site's own response headers add a second lock: a content security policy that lets no script run unless this site shipped it, so nothing injected into a page can reach your file either.
The exception is AI review, and it is the only one. If you set a provider key, the segments you select go to the provider you named and nowhere else. Everything on this page works with that feature switched off.
What it refuses to do
Stating this plainly, because it is most of the design.
- No server
- There is no upload endpoint and no file storage. This is not a privacy policy you are being asked to trust; there is nowhere for a file to be sent.
- No account
- No email address, no password, no session. Nothing here asks who you are, and there is no sign-up form on this site because there is nothing to sign up to.
- No cookies
- There is no cookie banner because there is nothing to consent to.
- It never translates for you
- There is no machine translation in this product. The AI feature reviews the translation you wrote and reports findings against the source; it does not fill your targets.
- It does not normalize your file
- Not the whitespace, not the entity style, not the line endings, not the byte order mark, not the attribute order, not the encoding. Those were decisions made by the tool that produced your file, and they are not ours to improve.
- It does not guess
- A CSV whose columns cannot be identified raises an error that names what to do about it. It does not take the first two columns and hope.
- A translation memory never carries markup between files
- It stores where a tag stood, never the tag, and fills those positions from your own document's source. A memory here cannot introduce foreign markup because it has nothing foreign to introduce.
What it does not do yet
- Gate C
- Real Trados Studio and real memoQ have not opened an export from this tool. It is the honest limit on the SDLXLIFF and MQXLIFF claim, and it is the reason the table above has no row about vendor applications.
- XLSX and CSV are not byte-identical, and cannot be
- An XLSX is a zip of XML parts, so there are no original bytes to splice into. The exporter opens your own workbook and edits the target cells in place rather than building a new one, so your formatting, formulas and extra sheets survive, but the zip is repacked. CSV has no stable byte layout beyond its dialect. For both formats the gates assert structural equality instead, which is the strongest claim those formats allow.
- No .sdltm, and no server-side memories
- Trados's own .sdltm is a SQLite database; memoQ server, Phrase and XTM memories need a network and credentials, which is a different product with a different privacy story. TMX is the interchange format all of them export, and TMX is supported.
- English only for now
- Eight other locale files exist, machine-filled and waiting on human review. The language switcher ships when they have had it.
- The tag picker is the flags column
- Ctrl+, inserts the next missing tag rather than opening a picker at the caret. Every missing tag is visible in the flags column, one click from insertion.
- Built for a desktop screen
- The editor opens on a phone, but below a laptop's width its toolbar is cropped and the two text columns get narrow. A layout for small screens is planned, not built.
- Your session lives in this browser
- Autosave writes to this browser's own storage on your own disk, so your work does not follow you to another machine, and opening a second file replaces the session stored for the first. The app says so before it does it.
Open one of your own files
Open a real job, export it without changing anything, and diff the two. That is a better answer to "what happens to my files" than anything on this page.