Tutoriels//8 min de lecture

Règles de pluralisation dans différentes langues : Guide du développeur

Eray Gündoğmuş
Partager

Règles de pluralisation dans différentes langues : Guide du développeur

Vous avez livré une fonctionnalité. Les traductions sont intégrées. Tout semble parfait en anglais. Puis quelqu'un signale un bug : « L'appli dit "1 articles dans le panier" et "5 article dans le panier". » Vous corrigez cela avec un opérateur ternaire rapide. Six mois plus tard, un utilisateur en Pologne signale que l'application affiche du texte grammaticalement incorrect partout. Vous n'avez pas cassé la pluralisation — vous ne l'avez jamais vraiment résolue.

La pluralisation est l'un des problèmes les plus sous-estimés de l'internationalisation. La plupart des développeurs la traitent comme un problème binaire propre à l'anglais : singulier contre pluriel. Mais les langues naturelles sont bien plus complexes que cela, et en i18n de production, cette complexité se fait ressentir durement. Ce guide explique comment la pluralisation fonctionne réellement d'une langue à l'autre, comment l'implémenter correctement et comment éviter les erreurs qui passent entre les mailles de chaque revue de code.

Si vous débutez avec les concepts d'internationalisation de manière générale, le guide sur la localisation et l'internationalisation offre une base utile avant de plonger dans les mécanismes de pluralisation spécifiques à chaque langue.


Pourquoi la pluralisation est plus importante que vous ne le pensez

Voici un schéma courant dans les bases de code :

const label = count === 1 ? 'article' : 'articles';

Cela fonctionne pour l'anglais. Pour exactement deux langues : l'anglais et une poignée de langues similaires. Dès que vous déployez en turc, arabe, russe ou polonais, cette approche produit des absurdités — ou pire, un texte subtilement incorrect d'une manière qui semble irrespectueuse envers les locuteurs natifs.

Les erreurs de pluralisation en production ont de véritables conséquences :

  • Érosion de la confiance : Les locuteurs natifs reconnaissent immédiatement une mauvaise grammaire. Cela indique que le produit n'a pas été conçu pour eux.
  • Risque juridique : Dans certaines régions, les expressions de quantité dans les contrats, les factures ou les textes de conformité doivent être grammaticalement correctes.
  • Échecs d'accessibilité : Les lecteurs d'écran et les outils d'assistance dépendent d'un texte grammaticalement correct.

La cause profonde est presque toujours la même : les développeurs codent en dur la logique plurielle anglaise, puis les traducteurs reçoivent une chaîne sans contexte sur la forme à utiliser.


Les pluriels anglais : Trompeusement simples

L'anglais a deux formes plurielles : le singulier (1) et le pluriel (tout le reste). Cela se mappe proprement sur une expression ternaire, c'est pourquoi les développeurs l'utilisent par défaut.

// Anglais : deux formes, singulier et pluriel
`${count} ${count === 1 ? 'fichier' : 'fichiers'} téléversé(s)`

Mais même en anglais, cela se complique avec les cas limites :

  • Zéro : « 0 fichiers » se lit naturellement, mais certaines interfaces préfèrent « Aucun fichier ». C'est une décision de conception, pas de traduction — mais elle nécessite quand même la prise en charge des formes plurielles.
  • Fractions : « 1,5 fichier » est grammaticalement ambigu. L'anglais utilise généralement le pluriel pour les valeurs non entières, mais cela varie selon le domaine.
  • Noms irréguliers : « 1 personne » / « 2 personnes », « 1 enfant » / « 2 enfants ». Ceux-ci ne sont pas gérés par de simples règles de suffixe.

L'anglais semble simple parce qu'il l'est, relativement parlant. Dès que vous le quittez, la complexité augmente de façon dramatique.


Comment les autres langues gèrent les pluriels

Arabe : Six formes

L'arabe possède six formes plurielles grammaticalement distinctes selon le nombre :

FormeNombres
zero0
one1
two2
few3–10
many11–99
other100+ (et décimaux)

Chaque forme nécessite un mot ou un suffixe différent. La chaîne « Vous avez X messages » nécessite six traductions en arabe, pas deux. Envoyer uniquement le singulier et le pluriel à un traducteur arabophone revient à lui demander de deviner — ce qu'il ne peut pas faire, car la structure du message diffère pour chaque forme.

Russe et polonais : Trois à quatre formes avec des règles complexes

Le russe utilise trois formes : singulier (1), few (2–4 et les nombres se terminant par 2–4, sauf 12–14) et many (tout le reste).

La règle pour le russe n'est pas triviale :

n % 10 === 1 && n % 100 !== 11  → singulier
n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) → few
tout le reste → many

Ainsi : « 21 файл » (singulier), « 22 файла » (few), « 25 файлов » (many), « 11 файлов » (many — pas singulier, car 11 est une exception).

Le polonais ajoute une complexité supplémentaire avec quatre formes et des limites légèrement différentes. Si vous vous trompez, un utilisateur russe ou polonais le remarque immédiatement. Ce ne sont pas des cas limites obscurs — ce sont des nombres qui apparaissent dans les interfaces quotidiennes.

Japonais, chinois, coréen : Aucun pluriel

Ces langues ne distinguent pas grammaticalement le singulier du pluriel. « 1 fichier » et « 100 fichiers » utilisent la même forme nominale. La quantité est exprimée par des chiffres, des compteurs (classificateurs) ou le contexte.

Cela signifie :

  1. Vous ne devez pas envoyer de formes plurielles aux traducteurs pour ces langues — vous leur demandez de traduire des distinctions qui n'existent pas.
  2. Le nombre est toujours affiché, mais il n'influe pas sur le nom.
  3. Un mauvais traitement des pluriels se manifeste généralement ici par des traducteurs qui dupliquent la forme « other », ce qui est techniquement acceptable mais peut produire des formulations redondantes ou peu naturelles.

Autres cas notables

  • Langues slaves en général (tchèque, slovaque, croate) : Trois à quatre formes, règles modulo complexes.
  • Gallois : Six formes avec des limites très irrégulières.
  • Gaélique (écossais et irlandais) : Formes qui se divisent sur 1, 2, 3–10, 11–19 et 20+.
  • Hébreu : Formes distinctes pour le singulier, le duel (exactement 2) et le pluriel.

Le standard CLDR des règles plurielles

Le Référentiel Commun de Données de Localisation Unicode (CLDR) définit les règles plurielles pour toutes les langues principales. Ce sont les règles canoniques utilisées par les navigateurs, les systèmes d'exploitation et les bibliothèques i18n. Le CLDR catégorise les formes plurielles en six catégories nommées :

  • zero
  • one
  • two
  • few
  • many
  • other

Chaque langue utilise un sous-ensemble de celles-ci. L'anglais utilise one et other. L'arabe utilise les six. Le japonais n'utilise que other.

Ces règles sont disponibles sous forme lisible par machine et sont déjà intégrées dans la plupart des bibliothèques i18n matures. Vous n'avez pas besoin d'implémenter les calculs vous-même. Vous devez comprendre que ces catégories existent et que votre flux de travail de traduction doit prendre en compte toutes les formes qu'une langue donnée requiert.


ICU MessageFormat : La bonne abstraction

ICU MessageFormat est le standard le plus largement pris en charge pour exprimer la pluralisation dans les chaînes de traduction. Il intègre la logique plurielle dans le message lui-même, de sorte que les traducteurs peuvent gérer chaque forme de manière indépendante.

La syntaxe pour l'anglais :

{count, plural,
  one {# fichier téléversé}
  other {# fichiers téléversés}
}

Pour le russe (tel que fourni par un traducteur qui connaît la langue) :

{count, plural,
  one {Загружен # файл}
  few {Загружено # файла}
  many {Загружено # файлов}
  other {Загружено # файлов}
}

Le # est remplacé par le nombre réel. La bibliothèque évalue la règle plurielle pour la locale active et choisit la bonne forme.

Cette approche présente des avantages décisifs par rapport à la concaténation de chaînes :

  1. Chaque forme est une phrase complète, de sorte que les traducteurs disposent du contexte grammatical complet.
  2. Pas d'assemblage de chaînes au moment de l'exécution — le message est résolu en une chaîne finale avant l'affichage.
  3. Formes appropriées à la langue — les traducteurs fournissent exactement les formes dont leur langue a besoin.
  4. Prise en charge des outils — les linters, les outils d'extraction et les plateformes de traduction comprennent ce format.

Implémenter la pluralisation avec i18next

i18next est l'une des bibliothèques i18n les plus utilisées dans l'écosystème JavaScript, et elle gère les règles plurielles CLDR nativement.

Configuration de base

import i18next from 'i18next';

i18next.init({
  lng: 'en',
  resources: {
    en: {
      translation: {
        file_count: '{{count}} fichier',
        file_count_other: '{{count}} fichiers',
      },
    },
  },
});

i18next utilise une convention de suffixe de clé : key pour la forme singulière, key_other pour le pluriel par défaut et key_zero, key_one, key_two, key_few, key_many pour les formes CLDR supplémentaires. Vous passez count comme variable d'interpolation, et la bibliothèque sélectionne automatiquement la bonne clé.

i18next.t('file_count', { count: 1 });   // "1 fichier"
i18next.t('file_count', { count: 5 });   // "5 fichiers"

Intégration React

Avec react-i18next :

import { useTranslation } from 'react-i18next';

function FileCount({ count }: { count: number }) {
  const { t } = useTranslation();
  return <span>{t('file_count', { count })}</span>;
}

Pour les configurations /i18n/react, c'est le schéma recommandé. La variable count pilote à la fois l'interpolation (affichage du nombre) et la sélection de la forme plurielle.

Gestion de plusieurs formes CLDR

Pour le russe, votre fichier de traduction doit contenir toutes les formes requises :

{
  "file_count_one": "{{count}} файл",
  "file_count_few": "{{count}} файла",
  "file_count_many": "{{count}} файлов",
  "file_count_other": "{{count}} файлов"
}

i18next applique la règle CLDR correcte pour la locale et choisit la bonne clé. L'évaluation des règles est intégrée — vous n'écrivez pas la logique modulo vous-même.

Next.js avec next-i18next

Pour les applications /i18n/nextjs utilisant next-i18next, le schéma est le même mais les traductions se trouvent dans public/locales/{lng}/{ns}.json :

// public/locales/ru/common.json
{
  "file_count_one": "{{count}} файл",
  "file_count_few": "{{count}} файла",
  "file_count_many": "{{count}} файлов",
  "file_count_other": "{{count}} файлов"
}
import { useTranslation } from 'next-i18next';

export function FileCount({ count }: { count: number }) {
  const { t } = useTranslation('common');
  return <p>{t('file_count', { count })}</p>;
}

Pièges courants

1. Mauvais nom de variable

i18next utilise count spécifiquement pour déclencher la sélection de la forme plurielle. L'utilisation de tout autre nom de variable contourne entièrement la logique plurielle :

// MAUVAIS — la sélection plurielle ne se déclenchera pas
t('file_count', { number: 5 });

// CORRECT
t('file_count', { count: 5 });

C'est un échec silencieux. La forme de secours (_other) est utilisée, de sorte que l'anglais peut sembler correct tandis que les autres langues se cassent silencieusement.

2. Formes plurielles manquantes pour la locale cible

Si vous ne définissez que key et key_other pour une locale russe, la bibliothèque revient à key_other pour toutes les formes. Les utilisateurs russes reçoivent du texte grammaticalement incorrect et il n'y a aucune erreur dans la console. C'est le bug de pluralisation le plus courant dans les logiciels livrés.

La solution consiste à exiger toutes les formes CLDR pour chaque locale avant la livraison. Automatisez cette vérification — ne faites pas confiance à la revue manuelle.

3. Concaténation de chaînes au lieu de clés plurielles

// MAUVAIS
const message = t('you_have') + ' ' + count + ' ' + t('messages');

// CORRECT — le nombre et les mots environnants forment une unité traduisible
t('you_have_messages', { count });

La concaténation rend structurellement impossible la gestion des langues où l'ordre des mots, la forme nominale ou l'accord verbal changent avec le nombre. La phrase entière contenant le nombre doit être une seule clé de traduction.

4. Confondre les ordinaux avec les pluriels cardinaux

Les nombres ordinaux (« 1er », « 2e », « 3e ») suivent des règles complètement différentes des pluriels cardinaux. Ne les confondez pas. i18next dispose d'une prise en charge ordinale séparée via l'option ordinal: true :

t('position', { count: 1, ordinal: true });  // "1re place"
t('position', { count: 2, ordinal: true });  // "2e place"

Les règles ordinales sont également spécifiques à la locale — le français, par exemple, utilise « 1er » pour le premier, puis le même suffixe pour tous les ordinaux suivants.

5. Traiter zéro comme une forme plurielle spéciale

Certains designs prévoient « Aucun fichier » plutôt que « 0 fichier ». Ce n'est pas une forme plurielle — c'est une décision d'interface. Gérez-la explicitement dans le code avant d'appeler la fonction de traduction, ou utilisez une clé de traduction séparée :

const key = count === 0 ? 'no_files' : 'file_count';
t(key, { count });

Ne vous fiez pas à la forme CLDR zero pour les décisions de texte d'interface. La forme zero existe pour les langues qui distinguent grammaticalement zéro des autres valeurs, pas comme un crochet de conception.


Tester les traductions plurielles

La gestion des pluriels est notoirement peu testée. Pour une vue plus large de la façon de structurer votre processus qualité i18n, le guide sur les outils de test i18n et les stratégies d'automatisation couvre les outils qui peuvent être intégrés aux côtés de ces schémas.

Tests aux valeurs limites

Testez chaque valeur limite pour les locales que vous livrez :

const testCounts = [0, 1, 2, 3, 4, 5, 11, 12, 21, 22, 100, 101];

for (const count of testCounts) {
  console.log(`${count}: ${t('file_count', { count })}`);
}

Pour le russe spécifiquement : 1, 2, 5, 11, 12, 21, 22, 25, 100, 101, 111, 121.

Tests de snapshot pour chaque locale

describe('pluralisation file_count', () => {
  it.each([
    ['en', 1, '1 file'],
    ['en', 5, '5 files'],
    ['ru', 1, '1 файл'],
    ['ru', 2, '2 файла'],
    ['ru', 5, '5 файлов'],
    ['ru', 11, '11 файлов'],
    ['ru', 21, '21 файл'],
    ['ar', 1, '1 ملف'],
    ['ar', 3, '3 ملفات'],
  ])('locale %s, count %d → %s', (lng, count, expected) => {
    i18next.changeLanguage(lng);
    expect(i18next.t('file_count', { count })).toBe(expected);
  });
});

Cela détecte les formes manquantes, les mauvaises limites CLDR et les erreurs de traduction avant qu'elles n'atteignent les utilisateurs.

Lint pour les formes manquantes

Écrivez un script qui lit vos clés de locale source, identifie toutes les clés plurielles (celles se terminant par _other) et vérifie ensuite chaque locale cible pour les formes CLDR requises par cette locale. Faites échouer la CI si des formes sont manquantes. Cela prévient entièrement la classe de bugs de fallback silencieux.


Où la sécurité des types change la donne

Une faiblesse de l'i18n basée sur des chaînes de clés est que rien n'impose une utilisation correcte au site d'appel. Vous pouvez passer number au lieu de count, omettre complètement le count, ou référencer une clé qui n'existe pas — et tout cela échoue silencieusement à l'exécution.

Les outils i18n avec sécurité des types génèrent des types TypeScript à partir de vos clés de traduction, de sorte que le compilateur détecte :

  • Les variables d'interpolation requises manquantes
  • L'utilisation du mauvais nom de variable (number vs count)
  • La référence à des clés inexistantes

Better i18n s'appuie sur ce modèle avec des SDK qui comprennent votre schéma de traduction et imposent l'exhaustivité plurielle au moment de la publication. Lorsque vous ajoutez une nouvelle clé plurielle, le SDK génère des types mis à jour — et tout site d'appel qui ne fournit pas la variable count requise devient une erreur de type. Pour les équipes gérant des dizaines de locales avec des centaines de clés, cela intercepte toute une classe de bugs de pluralisation avant la revue de code.

Les fonctionnalités de la plateforme les plus importantes pour la pluralisation sont : l'exhaustivité des formes imposée (toutes les formes CLDR requises doivent être présentes avant la publication), la traduction par IA qui comprend le contexte (« c'est un nombre de fichiers, utilisez la forme plurielle appropriée »), et l'application du glossaire pour que les noms spécifiques au domaine soient déclinés de manière cohérente.

L'exactitude de la pluralisation est également profondément liée à un flux de travail bien structuré de traduction et localisation de site web — lorsque les formes plurielles sont collectées et examinées dans le cadre du même processus que le reste de la traduction, il est beaucoup moins probable qu'elles passent incomplètes.


Résumé pratique

Une pluralisation correcte nécessite :

  1. Utilisez ICU MessageFormat ou une bibliothèque qui implémente les règles CLDR. N'écrivez pas votre propre logique plurielle.

  2. Utilisez toujours count comme variable d'interpolation dans i18next. D'autres noms contournent la sélection plurielle.

  3. Fournissez toutes les formes CLDR pour chaque locale. Vérifiez quelles formes une langue requiert avant d'envoyer des chaînes aux traducteurs.

  4. Ne concaténez jamais des chaînes avec des nombres. La phrase entière est une clé de traduction.

  5. Testez les valeurs limites pour chaque locale. Notamment le russe, le polonais, l'arabe et les autres langues à règles complexes.

  6. Imposez l'exhaustivité des formes dans la CI. Les formes plurielles manquantes entraînent des fallbacks silencieux invisibles lors des tests en anglais.

  7. Distinguez les ordinaux des cardinaux. Ils suivent des règles différentes et nécessitent un traitement séparé.

Les outils existent pour faire cela correctement. Les règles CLDR sont standardisées. Les bibliothèques les implémentent. Le mode d'échec dans la plupart des bases de code n'est pas technique — c'est supposer que la logique plurielle anglaise se généralise, et ne pas construire le flux de travail pour détecter quand ce n'est pas le cas.


Rendez votre application mondiale avec better-i18n

better-i18n combine des traductions alimentées par l'IA, des flux de travail natifs git et une diffusion CDN mondiale dans une plateforme axée sur les développeurs. Arrêtez de gérer des tableurs et commencez à livrer dans toutes les langues.

Commencer gratuitement → · Explorer les fonctionnalités · Lire la documentation

Comments

Loading comments...