When localizing apps supported by many different platforms, you may benefit from our Format Conversions, manage just one project on Localazy synchronized with the selected platform, and convert translations to other platforms automatically.

One issue you may encounter along the way is that each platform uses different placeholders for the composite formatting.

🤖 Android vs. 🍎 iOS placeholders 🔗

For example, let's have a look at a simple iOS .strings with different placeholders:

"error_message" = "Error! Module %@ is not available. Visit %@ and enable it!"

For Android, you would, however, expect the following:

  <string name="error_message">Error! Module $1%s is not available. Visit $2%s and enable it!</string>

Technically, positional placeholders are also supported on iOS, but if you want to avoid rewriting all your resources, you can rely on Localazy CLI to solve this for you.

💡 The solution 🔗

In the conversions section of your localazy.json, you can define rules for replacing placeholders like this:

  "conversion": {
    "actions": [
        "type": "android",
        "output": "app/src/main/res/values-${langAndroidRes}/strings.xml",
        "replacements": {
          "REGEX:(%@)": "$(%o%)%s",
          "REGEX:%([a-zA-Z])": "$(%o%)%(%1%)"

The two replacement formulas above correctly handle %@ and also any other variant, such as %s, %d, etc., and convert them to positional placeholders.

Localazy supports (%o%) for 1-based index (1, 2, 3, …) and (%i%) for 0-based index (0, 1, 2, …).

Read more about format conversions and text replacements.

💖 You might also like 🔗

Read more articles related to Android, iOS, or Localazy CLI on our blog.

📚 Further reading: