GetTranslated.AI
Localization & Global Growth

Taming Localization Edge Cases: Input & Output Validation for Mobile Apps

If you've ever shipped a multilingual mobile app, you've probably encountered bugs that behave like undefined behavior in C++: everything works perfectly in testing until production reveals edge cases that only surface in specific locales.

Localization bugs follow similar patterns. A missing plural category in Polish, an unescaped ampersand in German, or a mismatched placeholder in Japanese can crash your app or silently fall back to English — often in ways that are impossible to catch during development.

This post covers the input and output validation pipeline we use for iOS, Android, and React Native projects. Think of it as running static analysis and sanitizers over your translation files, because these resources are effectively compiled assets that need the same rigor as your code.


Input Validation: Catching Issues Before Translation

Before any translation work begins, we parse and validate the base-language files. This is essentially precondition checking for resource files.

Duplicate Keys

Duplicate keys violate basic resource management principles. We reject them outright rather than allowing undefined behavior during compilation.

Structural Validation

Between XML (Android), .strings + .stringsdict (iOS), and JSON (React Native), there are countless ways to introduce syntax errors. We validate:

  • File structure and encoding
  • Escape sequence correctness
  • Platform-specific formatting requirements
  • Quote integrity and termination

An unescaped ampersand in Android XML or a missing semicolon in iOS strings will break your build. Better to catch these issues early.

Placeholder Safety

Placeholders function like API contracts — if you change the signature, all callers break. We verify that:

  • Placeholder counts match expectations
  • Order is preserved unless explicitly changed
  • Format specifiers are consistent (%s vs %@ vs {name})
  • Plural-specific placeholders maintain consistency

If one locale drops or adds a placeholder, that's not a warning — it's a runtime crash waiting to happen.


Plural Validation: Where Linguistics Gets Complex

Plurals are where most developers discover that natural language operates under different rules than programming languages.

Platforms handle plurals differently:

  • Android: Six possible categories (zero, one, two, few, many, other)
  • iOS: ICU rules implemented via .stringsdict files
  • React Native: Varies by i18n library, often messageformat-based

Languages differ even more dramatically.

Example: Polish Plural Logic

Polish demonstrates why plural validation matters. The rules look like they were designed by someone who writes template metaprogramming for entertainment:

  • one applies to numbers ending in 1, except 11
  • few applies to numbers ending in 2–4, except 12–14
  • many covers everything else
  • other exists because linguistic edge cases are infinite

This translates to logic roughly equivalent to:

if (n % 10 == 1 && n % 100 != 11) {
    return one;
} else if (n % 10 >= 2 && n % 10 <= 4 && !(n % 100 >= 12 && n % 100 <= 14)) {
    return few;
} else {
    return many;
}

This is essentially what ICU implements under the hood.

Why This Matters for Runtime Behavior

If your translation file lacks any required plural category, Polish users will see broken UI or fallback text. Both Android and iOS request specific categories based on the numeric value being displayed — if the translation cannot satisfy that request, your app enters undefined behavior territory.

The validator ensures:

  • All required categories exist for each language
  • No categories are missing or misspelled
  • Placeholders match across all plural forms
  • Platform-specific structure (like .stringsdict nesting) is correct

Polish is dramatic but not unique. Arabic plural rules are even more complex, involving different logic for different numeric ranges.


Output Validation: Verifying Translation Quality

LLMs are useful tools, but they occasionally behave like junior developers who "simplify" your interface by changing %1$s placeholders to %s and deciding JSON doesn't need proper comma placement.

Every translated file gets validated for:

Syntax Correctness

  • XML well-formedness
  • JSON structural validity
  • .strings quote and escape integrity
  • .stringsdict proper nesting and key presence

Platform-Specific Escaping

Each platform requires different escape sequences. LLMs don't inherently understand these requirements, so we enforce platform-specific rules during validation.

Placeholder Consistency

If a translation drops a placeholder, that's an error.
If a translation introduces a new placeholder, that's an error.
There are no "warnings" for placeholder mismatches — only binary pass/fail.

Plural Completeness

If a language requires six plural categories and the translation provides four, we reject the entire file. Plural rules are mandatory, not optional.


Testing Across 80+ Languages

To ensure consistent behavior, we run validation tests across all supported languages, verifying:

  • ICU plural rule compliance per language
  • Category completeness requirements
  • Placeholder consistency across plural forms
  • Structural correctness for each platform
  • Unicode handling and escape safety
  • Platform-specific differences between Android, iOS, and React Native

This approach catches edge cases that would otherwise surface only in production — including languages where "zero" doesn't map to "other," languages where plural categories depend on the final two digits, and languages where negative numbers follow different rules than zero.


Why Validation Prevents Production Issues

Without systematic validation, teams regularly encounter:

  • %@ vs %s format specifier mismatches causing crashes
  • Android builds failing due to unescaped XML content
  • .stringsdict files silently failing and falling back to English
  • i18next rendering object references instead of translated strings
  • Plural sets missing required categories for specific languages
  • CI failures that work perfectly in development environments

Validation eliminates these issues before they reach devices or production environments.


Conclusion

Localization bugs are subtle, platform-specific, and often catastrophic when they surface in production. By treating translations as compiled resources and validating them with the same rigor applied to source code, we eliminate entire classes of runtime failures.

Proper validation ensures that whether you're targeting English, Polish, Arabic, or any other language, your localized app behaves predictably across all platforms and locales.

Ready to localize your app?

Get started free — no credit card required.

Start Translating →