---
title: "How do I insert a variable into a localized string in Android?"
description: "Put positional placeholders such as `%1$s` and `%2$d` in the string resource and pass the values as format arguments to `getString()` or Compose's `stringResource()`. For counts, use quantity strings so every language gets the right plural form."
category: android
date: 2026-10-09
canonical: https://localizely.com/i18n-questions/android/how-do-i-insert-a-variable-into-a-localized-string-in-android/
---

# How do I insert a variable into a localized string in Android?

Put a positional placeholder in the resource and pass the value as a format argument. Do not build the sentence from concatenated pieces.

```xml
<string name="welcome">Hello, %1$s! You have %2$d new messages.</string>
```

```kotlin
// In an Activity, Fragment or anything else with a Context
val text = getString(R.string.welcome, userName, mailCount)

// In Jetpack Compose
Text(text = stringResource(R.string.welcome, userName, mailCount))
```

Both calls run `String.format()` with the current locale, using [`java.util.Formatter`](https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html) syntax: `%s` for strings, `%d` for integers, `%.2f` for decimals. The number before `$` is the argument position, so `%2$d` always takes the second argument wherever it appears in the sentence. That is what makes the string translatable: a translator can write "Du hast %2$d neue Nachrichten, %1$s!" and the code stays the same. Unpositioned `%s %d` only works while every language keeps the same order, and aapt2 warns when a string has several unpositioned placeholders.

Concatenation such as `getString(R.string.you_have) + count + getString(R.string.messages)` breaks as soon as a language puts the words in another order or inflects them differently, and it gives translators fragments they cannot translate in context.

When the variable is a count, the whole sentence changes with the number, so use a quantity string instead of a single string with `%d`:

```xml
<plurals name="new_messages">
    <item quantity="one">You have %d new message.</item>
    <item quantity="other">You have %d new messages.</item>
</plurals>
```

```kotlin
val text = resources.getQuantityString(R.plurals.new_messages, count, count)

// In Jetpack Compose
Text(text = pluralStringResource(R.plurals.new_messages, count, count))
```

The count is passed twice: once to select the plural form and once as the `%d` argument. Other languages need forms such as `few` and `many`; see the [plural rules per language](/language-plural-rules/).

Finally, wrap each placeholder in `<xliff:g>` so translators do not alter it: `<xliff:g id="name" example="Ana">%1$s</xliff:g>`. How that works is covered in [What is xliff:g in Android strings.xml and when should I use it?](/i18n-questions/android/what-is-xliff-g-in-android-strings-xml-and-when-should-i-use-it/). The official reference is the [Format strings](https://developer.android.com/guide/topics/resources/string-resource) section of the string resource guide.

Source: https://localizely.com/i18n-questions/android/how-do-i-insert-a-variable-into-a-localized-string-in-android/
