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 are written. The file you opened is kept, and export replaces the target ranges you edited; everything else is copied as it was.
  • Two automated gates test it. An unedited export must equal the input byte for byte, and an edit must change only its own segment's bytes.
  • Not yet tested in Trados Studio or memoQ. The bytes are proved; opening the result in the vendor tools is still to be done.

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

As your client sent it
<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>
As you export it, after fixing the translation and confirming the segment
<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.

Runs in this page. Nothing is uploaded.

Two ways to write a file

Parse to a tree, write the tree back

Original file Document tree New file, written from the tree

every byte rewritten

What xliff.ai does

Original file, kept Offsets only The same bytes, two ranges spliced

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 formats (SRT and WebVTT share one), and every column heading is a page explaining that format.

Scroll the table sideways to see every format.

What xliff.ai writes and what it leaves untouched, by format.
  XLIFF 1.2 XLIFF 2.0 SDLXLIFF MQXLIFF PO XLSX CSV SRT, WebVTT
Everything outside a segment you edited identicalidenticalidenticalidenticalidenticalstructuralstructuralidentical
Segment status on changeon changeon changeon changeon change not applicable not applicable not applicable
Match rate and origin not applicable not applicable identicalidentical not applicable not applicable not applicable not applicable
Comments and notes identicalidenticalidenticalidenticalidentical not applicable not applicable identical
Locked segments read-onlyread-onlyread-onlyread-only not applicable not applicable not applicable not applicable
Inline tag definitions identicalidenticalidenticalidentical not applicable not applicable not applicable not applicable
Namespace prefixes, attribute order, entity style, indentation identicalidenticalidenticalidentical not applicable not applicable not applicable not applicable
Encoding, byte order mark, line endings identicalidenticalidenticalidenticalidentical not applicable reproducedidentical
Sheet and column structure, cell types, formatting not applicable not applicable not applicable not applicable not applicable preserved not applicable not applicable
Subtitle numbers, timecodes and cue settings not applicable not applicable not applicable not applicable not applicable not applicable not applicable identical
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. In a PO file it is the fuzzy flag.
read-only
Visible, searchable and filterable. There is nothing to write, so nothing can be lost.
structural
A spreadsheet is a zip of XML parts. Only the edited sheet's XML is rewritten, at the cells you changed, and every other part is copied byte for byte. The file as a whole is not byte-identical, but sheet and column structure, row order, and the type and formatting of every cell you did not edit 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 29 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.

The same harness adds structural checks for the spreadsheet and CSV fixtures and refusal checks for the malformed ones.

The corpus is 62 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, 1,450 fuzz cases: each of the 29 byte-exact 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
Five exports, and a pseudo-translation tool
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; and a QA report as XLSX or CSV. Pseudo-translation is a separate tool with its own page. XLIFF to Excel Pseudo-translate
AI translation on your computer
In desktop Chrome and Edge, the AI panel translates with the translator built into the browser: no key, no cost and nothing sent, because the model runs on your computer. It fills empty targets as Draft, keeps inline tags by the same strict check, and drops any result that loses one. The first use of a language pair may make the browser download its model; Firefox, Safari and phones do not have one yet. Machine translation and tags
AI review and translation with your own key
Anthropic, OpenAI, Gemini, OpenRouter, DeepSeek, Azure OpenAI, or an endpoint you name. Review reports findings against the source; translation fills empty targets as Draft and drops any result that loses an inline tag. This is the one feature that sends text off your machine: only when you press the button, only to the provider you chose, and only the segments in your current view, each with two neighbouring segments on either side for context and any matching glossary terms. The key stays in this browser, and a session-only mode keeps it out of storage. Machine translation and tags
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. Or let the editor show you, with the network lock below. 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 the AI feature, review and translation, and it is the only one. If you set a provider key and press its button, the segments in your current view, each with two neighbouring segments for context and any matching glossary terms, go to the provider you named and nowhere else. The file itself never does. Everything on this page works with that feature switched off.

Read the privacy page

Lock the network, and count every request

In the editor's top bar, beside the progress, a padlock and a number count every request the editor page and its workers start after a file opens, including the ones this device answers itself and the ones to xliff.ai. Click it and turn on Refuse every request from this tab: from then on the editor refuses every request before it leaves, and says "Network lock is on" where something needed the network.

The lock is held twice. Inside the page and each of its workers, every way code can send a request (fetch, XMLHttpRequest, WebSocket, EventSource, beacons) is wrapped, so a request is stopped before it starts. And the editor's service worker, the part of your browser that keeps it working offline, refuses anything from the editor it cannot answer from this device: images, scripts and styles the browser fetches by itself, and anything that got past the first wall. The panel says "held twice" only once the service worker has confirmed it; where a browser runs none (Firefox's private windows, for one) it says the page alone holds the lock.

Everything already on this device keeps working: editing, QA, memories, glossaries, export, a reload of the editor, and spelling in any language whose dictionary you have used once. What needs the network waits until you turn the lock off, and says so: AI through a provider, and the first download of a spelling dictionary.

It is off until you turn it on, because a first file in a new language needs its dictionary and AI needs the network. Once on, it stays on in this browser, across reloads and files, until you turn it off.

The count never claims less than happened. A request is counted when it starts, so one that fails or never answers is counted too, and it is listed as answered by this device only when the browser's own timing record shows that nothing crossed the network and the service worker did not fetch it either. Two things are outside it, and the panel says so: a link you click, which leaves the editor, and your browser's own check for a new version of the editor when the page loads, which asks xliff.ai for one file and carries nothing of yours.

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 confirms for you
AI translation, on your computer or with your own key, writes Draft only. Nothing becomes Translated until you confirm it yourself, and one undo reverses a whole AI run.
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 silently
When a CSV or spreadsheet's headers do not say which column is the source and which the target, the columns are picked by their content and the file opens with a notice saying so. When no plausible pair of columns exists, it raises an error that names what to do about it.
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.
Not yet tried on an iPhone or iPad
On a screen narrower than 768 pixels, a phone or a small tablet held upright, each segment is a card: number, status and flags on one line, then the source and the target at full width. Tapping the status confirms a segment, so that needs no keyboard, but the shortcuts, Ctrl+Enter and the rest, need a physical one. Opening a whole folder works only in Chrome and Edge on a computer. The layout has been checked in a desktop browser's phone emulation, not on a real iPhone or iPad, and not in Safari's engine, which browsers on an iPhone or iPad run on.
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.