<xliff:g> wraps the part of a string that must stay exactly as written when the string is translated: format placeholders, product names, URLs, codes, symbols. It is a hint for translators and translation tools, not for your app. aapt2 removes the element while compiling, so the installed app only contains the text inside it.
Declare the namespace once on the root element, then wrap each protected part:
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="unread_count">You have <xliff:g id="count" example="3">%1$d</xliff:g> unread messages</string>
<string name="sync_with">Sync with <xliff:g id="product">Google Drive</xliff:g></string>
<string name="promo">Use code <xliff:g id="promo_code" example="SPRING20">%1$s</xliff:g> at checkout</string>
</resources>
id says what the placeholder stands for, and example shows a value it will be replaced with, so a translator looking at the first string knows it will read "You have 3 unread messages" and can choose the right grammar around it. The Android localization guide recommends both attributes whenever the app replaces the value at runtime.
Use it for anything a translator could plausibly translate or retype wrongly: %1$s and %2$d arguments (a changed or reordered placeholder crashes getString() at runtime), brand and product names, URLs and email addresses, code snippets, units and special characters. Ordinary sentences do not need it.
At build time aapt2 records the wrapped range as an untranslatable section and flattens the string without the element, so getString() returns the text as if the tag were never there; there is no runtime cost and no API to read the markup back. Nesting one xliff:g inside another is a compile error. Translation tools that understand Android XML, including most TMS platforms, keep the wrapped text intact and present it to translators as a locked placeholder.
Pitfalls:
xmlns:xliff declaration on <resources>, the XML parser rejects the file because the prefix is unbound.strings.xml is not an XLIFF file; the tag only borrows the XLIFF namespace. If you exchange real XLIFF files with translators, see the XLIFF file format.%1$s).Published Oct 9, 2026 · Markdown version