Localizely logo
  • Home
  • Getting started
  • How it works
  • Pricing
  • FAQ
Sign up

I18n questions · Android

What is xliff:g in Android strings.xml and when should I use it? 

<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:

  • Without the 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.
  • The tag protects the placeholder, not its position. Translators may still move it within the sentence, which is correct and is why placeholders should be positional (%1$s).

Published Oct 9, 2026 · Markdown version

Related Android localization questions:

Android localization files:

Learn about Android XML string resources
Localizely logo
About
Free tools
Boring stuff
  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • Compare
Newsletter
Copyrights 2026 © Localizely