Tag handling

Set tag_handling and the engine treats your input as markup rather than plain text: tags stay where they are, only text nodes are translated.

Values

ValueUse for
(omitted)Plain text. Anything that looks like a tag is treated as text.
htmlHTML fragments and full documents
xmlXML documents, XLIFF fragments, custom markup

Example

curl -X POST https://api.vizvuz.com/v1/translate \
  -H "Authorization: Bearer vz_live_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
        "text": ["<p>Your <strong>invoice</strong> is ready. <a href=\"/bill\">Open it</a>.</p>"],
        "target_lang": "DE",
        "tag_handling": "html"
      }'
{ "translations": [ { "detected_source_language": "EN",
  "text": "<p>Ihre <strong>Rechnung</strong> ist fertig. <a href=\"/bill\">Öffnen</a>.</p>" } ] }

What is translated and what is not

PartTranslated
Text nodesYes
Tag namesNo
Attribute namesNo
Attribute values, including href, class, id, srcNo
Content of <code>, <pre>, <script>, <style>No
HTML commentsNo

Attribute values are deliberately left alone. Translating a class would break your CSS, and translating an href would break your links. If you need a title or alt attribute translated, send it as its own text.

Placeholders and variables

Interpolation markers survive as long as they are visibly not words. These are safe:

{name}   {{count}}   %s   %1$s   ${total}   :placeholder

Send them inside the text and they come back unchanged. If your placeholder syntax is unusual, wrap it in a tag and use xml:

<seg>Hello <x id="1"/>, you have <x id="2"/> new messages.</seg>

Whitespace

With preserve_formatting: true the engine keeps leading and trailing whitespace, line breaks and the capitalisation of the first character exactly as sent. Use it when your strings are fragments that get concatenated — otherwise a translated fragment may arrive capitalised and break the sentence it is glued into.

Characters still count

Markup counts towards your bill. Every <, every attribute and every closing tag is a character you sent, so it is a character we count. Two habits keep the bill down:

  1. Send fragments rather than full pages. Translating a 40 kB page to change 2 kB

of copy pays for the boilerplate every time.

  1. Strip inline <style> and <script> blocks before sending. They are never

translated, but they are always counted.

Malformed markup

The engine is tolerant: unclosed tags are returned as sent, and it will not "repair" your document. It is also not a validator — if your input is broken, the output is broken the same way. Validate before you send if that matters.

Combining with glossaries

Glossary terms are matched inside text nodes, so a glossary works normally with tag handling on. A term split across two tags — <b>in</b>voice — will not match; that is a markup problem, not a glossary problem.

Last updated Sep 1, 2026, 12:00 AM