Understanding Plural Rules in App Localization

Learn how different languages handle plural forms and why getting them right matters for your app's user experience.

English has two plural forms: "1 item" and "2 items." Seems simple. Then you try to localize your app into Russian and discover it needs four forms. Arabic needs six. Japanese needs one.

Welcome to CLDR plural rules.

English plural forms for "%lld file selected"
onen = 11 file selected
othern ≠ 15 files selected
English uses just two categories. Russian uses four. Arabic uses six.

The English Illusion#

In English, we split the world into singular and plural. One thing, or more than one thing. Easy.

But that's not universal. Russian distinguishes between "one file," "a few files," "many files," and "other files"—and which category a number falls into depends on its last digits. Twenty-one goes back to the singular form. Twenty-two through twenty-four use "few." Twenty-five through thirty use "many."

Arabic is wilder. It has special forms for zero, one, two, a few (3-10), many (11-99), and everything else.

Japanese? It doesn't distinguish at all. Every quantity uses the same form.

The Six Categories#

The Unicode CLDR standard defines six plural categories that languages can use:

CategoryUsed ByExample
zeroArabic, Welsh, Latvian"No files"
oneMost languages"1 file"
twoArabic, Welsh, Slovenian"2 files" (special form)
fewSlavic languages, Arabic"3 files" (Russian: файла)
manySlavic languages, Arabic"5 files" (Russian: файлов)
otherAll languages (required)Fallback for everything else

Every language uses a subset. English uses one and other. Russian uses one, few, many, and other. Japanese only uses other.

The other category is required in every language—it's the fallback. If you skip it, your app crashes or shows empty strings.

How Xcode Handles This#

When you write Swift code with a plural:

Text("\(count) items remaining")

Xcode extracts it as a plural string in your .xcstrings file:

{
  "variations": {
    "plural": {
      "one": {
        "stringUnit": { "value": "%lld item remaining" }
      },
      "other": {
        "stringUnit": { "value": "%lld items remaining" }
      }
    }
  }
}

When you add translations, each language gets its own set of plural forms based on its CLDR rules.

How XCStrings Translator Helps#

Manually figuring out which plural forms each language needs is tedious. XCStrings Translator handles this automatically:

  1. Detects that a string has plural variations
  2. Shows only the categories the target language needs
  3. Translates all required forms in one batch
  4. Validates that nothing is missing

Translate a plural string to German, and you'll see two fields (one/other). Translate to Russian, and you'll see four (one/few/many/other). Translate to Japanese, and you'll see just one (other).

Key
Source
Translation
State
%lld files selected
%lld files selected
Translated
one
%lld file selected
%lld Datei ausgewählt
Translated
other
%lld files selected
%lld Dateien ausgewählt
Translated
%lld days ago
%lld days ago
Translated
one
%lld day ago
vor %lld Tag
Translated
other
%lld days ago
vor %lld Tagen
Translated

Common Mistakes#

Hardcoding English patterns. Don't do this:

// Wrong - only works for English
Text("\(count) " + (count == 1 ? "item" : "items"))

Instead, let the system handle pluralization:

// Right - works for all languages
Text("\(count) items")

Xcode automatically extracts this as a plural string and generates the correct forms for each language.

Forgetting other. Every plural string needs an other case. It's the fallback. Skip it and you'll get crashes or empty strings.

Testing only with 1 and 2. Test with 0, 1, 2, 5, 11, 21, 22, 25, 100. Different languages have different breakpoints.

Ready to translate your app?

Download XCStrings Translator and start localizing your iOS and macOS apps with AI-powered translations.

Download for macOS