Lesson 3.2: Plurals, ICU MessageFormat & Complex Rules
Understand the 6 CLDR plural categories and ICU MessageFormat syntax.
1. Human Impact & Context
In English, pluralization seems simple. We have two basic states: singular (1 item) and plural (0 items, 2 items, 100 items). Because of this, developers frequently write naïve code like this:
JavaScript
javascript// BAD: English-centric plural code let message = count + (count === 1 ? " file deleted" : " files deleted");
When this code is deployed globally, it creates embarrassing grammatical errors:
In Russian:
21 filerequires the singular form (21 файл),2 filerequires a different form (2 файла), and5 filerequires a third (5 файлов). Naive English logic breaks Russian UI completely.In Arabic: The language uses six distinct plural forms depending on the exact number (Zero, One, Two, Few, Many, Other).
In Polish:
1 file(1 plik),2 files(2 pliki), and5 files(5 plików) follow distinct cardinal count rules.
To build software that handles global numbers without writing custom if/else conditions for every language on Earth, localization engineers use ICU MessageFormat—a standardized syntax supported across React, Android, iOS, Angular, and backend platforms.
2. Core Mechanics & Technical Concepts
The 6 Unicode CLDR Plural Categories
The Unicode Common Locale Data Repository (CLDR) defines 6 official plural categories for internationalization:
Swipe or scroll sideways to see more.
Category | Typical Meaning / Example | Target Languages |
|---|---|---|
| Explicit zero count ( | Arabic, Latvian, Welsh |
| Singular count ( | English, Spanish, Russian, Polish, Arabic |
| Exact dual count ( | Arabic, Hebrew, Welsh |
| Small numbers ( | Russian, Polish, Czech, Arabic |
| Larger count rules ( | Russian, Polish, Arabic |
| General fallback (required in ALL locales; default for Japanese/Chinese) | Universal |
Crucial Rule: Never invent custom category names. You must strictly use Unicode CLDR keys:
zero,one,two,few,many, andother.
ICU MessageFormat Plural Syntax
ICU MessageFormat encapsulates dynamic plural logic directly inside a single localized string asset using brace syntax:
{ variable_name, plural,
one { singular_pattern }
other { plural_pattern }
}English ICU Plural Example
JSON
json{ "cart_summary": "{itemCount, plural, one {You have {itemCount} item in your cart.} other {You have {itemCount} items in your cart.}}" }
Polish ICU Plural Example
In Polish, 1 uses one, 2–4 uses few, and 5–21 (or 0) uses many:
JSON
json{ "cart_summary": "{itemCount, plural, one {Masz {itemCount} koszyk.} few {Masz {itemCount} koszyki.} many {Masz {itemCount} koszyków.} other {Masz {itemCount} koszyków.}}" }
Explicit Exact Matches (=0, =1)
ICU MessageFormat allows developers to override grammatical rules with explicit zero or one matches for better UI copy (e.g., replacing "0 items" with "No items"):
JSON
json{ "inbox_status": "{unreadCount, plural, =0 {Your inbox is empty.} =1 {You have 1 unread message.} other {You have {unreadCount} unread messages.}}" }
The # symbol inside ICU plural blocks acts as a shorthand placeholder for the count variable itself:
JSON
json{ "file_count": "{count, plural, =0 {No files selected.} one {# file selected.} other {# files selected.}}" }
3. Real-World Industry Application
┌─────────────────────────────────────────┐
│ ICU Plurals Across L10n Logic │
└────────────────────┬────────────────────┘
│
┌─────────────────────────────────┼─────────────────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ Software UI │ │ Game UI │ │ Linear Media │
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
│ │ │
▼ ▼ ▼
Shopping Carts & Alerts Inventory & Quests Episode & Subtitle Logs
Calculates cart item counts, Tracks quest objectives Renders countdown timers and
unread notifications, and ("Kill 5 goblins") across remaining episode counts
storage limits dynamically. Slavic/Arabic game builds. in streaming video players.
Software UI: E-commerce apps use ICU plurals so shopping cart badges render grammatically correct strings across English (
1 item), Polish (2 koszyki), and Arabic (3dual forms).Game Localization: RPG quest trackers use CLDR categories (
few,many) to ensure quest progress counters ("Defeated 2 monsters") update naturally across regional releases.Linear Media (Subtitling): Video platforms display dynamic time-remaining banners (
"Season expires in # days") using ICU syntax to prevent awkward "1 days remaining" subtitle captions.
4. Cross-Platform Execution (Validating ICU Syntax in VS Code)
When working with ICU MessageFormat strings in Visual Studio Code:
Check Matching Braces: Every opening brace
{must have a corresponding closing brace}. Missing braces break runtime string interpolation.Verify Required
otherFallback: Theothercategory is mandatory in every ICU plural block across all languages.Keep Variable Identifiers Verbatim: Ensure the counter variable inside the ICU block (e.g.,
{count, plural, ...}) matches the source code parameter name exactly.
5. Next Steps & Lab Practice
Now that you understand the 6 CLDR plural categories and ICU MessageFormat syntax, you are ready to construct dynamic multilingual plural assets.
Proceed to 🛠️ Hands-On Lab 3.2: ICU Plural Syntax & CLDR Matching, or create a quick knowledge check!
Ready to move on?
Mark this lesson complete when you’re ready.