Plural- und Select-Formen kommen immer dann ins Spiel, wenn ein einzelner Ausgangsstring nicht ausreicht — die Übersetzung hängt dann von einer Zahl oder Kategorie ab. @lingo.dev/react bietet dafür zwei praktische Helfer (l.plural und l.select), die unter der Haube zu ICU MessageFormat kompiliert werden. So arbeiten Übersetzer mit der Standardsyntax, während die Runtime gleich bleibt.
Pluralformen#
l.plural(count, forms, { context }) wählt anhand von count und den CLDR-Pluralregeln der Sprache die passende Form aus.
const l = useLingo();
l.plural(items.length, {
one: "1 item",
other: "{count} items",
}, { context: "Cart summary" });
// → "1 item" (en, count=1) / "5 items" (en, count=5)
// → "1 Eintrag" / "5 Einträge" (de, after translation)Formen nach Sprache#
Das Formen-Mapping unterstützt alle CLDR-Pluralkategorien — zero, one, two, few, many, other. Jede Sprache nutzt davon, was sie braucht:
- Englisch verwendet
one+other(1 vs. alles andere) - Russisch verwendet
one+few+many+other(1; 2–4; 5–20; 21, 31, ...) - Arabisch verwendet alle sechs
- Japanisch verwendet nur
other(keine Pluralunterscheidung)
Du musst nur die Formen angeben, die die Ausgangssprache verwendet — Übersetzer ergänzen den Rest für die jeweilige Zielsprache.
{count} wird innerhalb jeder Pluralform automatisch interpoliert. Du übergibst es nicht über values — es stammt aus dem ersten Argument.
Kombination mit anderen Platzhaltern#
Bei Sätzen mit sowohl einer Anzahl als auch weiteren Variablen schreibst du die Variablen direkt in die Form-Strings; sie werden an ICU durchgereicht.
l.plural(notifications.length, {
one: "1 message from {sender}",
other: "{count} messages from {sender}",
}, { context: "Inbox header" });Übergebe die Werte dann beim Aufruf — aber Moment: Die Signatur von l.plural enthält doch nur { context }. Für gemischte Fälle verwendest du direkt l.text mit ICU-Pluralsyntax:
l.text(`{count, plural, one {1 message from {sender}} other {# messages from {sender}}}`, {
values: { count: notifications.length, sender: user.name },
context: "Inbox header",
});Das Token # wird wörtlich durch den Zählwert ersetzt — praktisch, wenn du es ohne die Interpolationsform mit geschweiften Klammern verwenden möchtest.
Select#
l.select(value, forms, { context }) wählt eine Form anhand eines String-Schlüssels aus (Geschlecht, Rolle, Inhaltstyp — alles, was kategorisch ist).
l.select(user.gender, {
male: "He uploaded a photo",
female: "She uploaded a photo",
other: "They uploaded a photo",
}, { context: "Activity feed" });other ist als Fallback erforderlich. Der Abgleich ist exakt — es gibt kein unscharfes oder von Groß-/Kleinschreibung unabhängiges Matching.
Selectordinal#
Für Ordnungszahlen (1., 2., 3.) verwendest du ICU selectordinal direkt über l.text:
l.text(`You finished in {place, selectordinal, one {#st} two {#nd} few {#rd} other {#th}} place`, {
values: { place: rank },
context: "Leaderboard",
});
// → "You finished in 1st place" / "2nd" / "3rd" / "4th, 5th, ..."Wozu das kompiliert wird#
Sowohl l.plural als auch l.select erzeugen einen ICU-MessageFormat-String und übergeben ihn an l.text. Die kompilierte Form wird von lingo extract extrahiert und in deinen Sprachdateien gespeichert — Übersetzer bearbeiten also direkt die ICU-Syntax, nicht das JS-Objektliteral.
Beispiel: l.plural(n, { one: "1 item", other: "{count} items" }, { context: "Cart" }) wird extrahiert als:
{count, plural, one {1 item} other {{count} items}}Das heißt: Übersetzer können die Kategorien pro Sprache anpassen — auch solche, die es in der Ausgangssprache nicht gibt. Russisch wird so zu {count, plural, one {...} few {...} many {...} other {...}}, ganz ohne Codeänderung.
Wann du sie nicht verwenden solltest#
- Ein einfaches "1 oder viele"-Boolean. Zwei
l.text-Aufrufe innerhalb einesifsind völlig okay und für Übersetzer leichter zu erkennen. - Ein programmatisches Enum ohne Nutzerbezug. Plural / Select sind für die Übersetzung kategorialer Meldungen gedacht, nicht für die Steuerung der App-Logik.
Wie geht's weiter?#
- useLingo — grundlegende Semantik von
l.textundl.rich. - Formatting — Zahlen-, Währungs-, Datums- und Listenformatierung mit dem nativen Intl.
