JavaScript internationalization library providing translation, interpolation, and pluralization capabilities.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Advanced pluralization system supporting multiple languages with complex plural rules and locale-aware plural form selection.
Get or set the current locale for pluralization rules.
/**
* Get or set current locale for pluralization
* @param {string} newLocale - Optional new locale to set
* @returns {string} Current locale string
*/
locale(newLocale);Usage Examples:
const Polyglot = require('node-polyglot');
const polyglot = new Polyglot({
phrases: {
'items_zero': 'No items',
'items_one': 'One item',
'items_other': '%{smart_count} items'
},
locale: 'en'
});
// Get current locale
console.log(polyglot.locale()); // "en"
// Set new locale
polyglot.locale('ru');
console.log(polyglot.locale()); // "ru"
// Locale affects pluralization behavior
polyglot.t('items', { smart_count: 2 }); // Uses Russian plural rules
// Reset to English
polyglot.locale('en');
polyglot.t('items', { smart_count: 2 }); // "2 items"Static method for phrase transformation without creating a Polyglot instance.
/**
* Static method for phrase transformation without instance creation
* @param {string} phrase - Phrase to transform with pluralization delimiters
* @param {Object|number} substitutions - Substitution values or smart_count shortcut
* @param {string} locale - Locale for pluralization rules (default: 'en')
* @returns {string} Transformed phrase with pluralization and interpolation applied
*/
Polyglot.transformPhrase(phrase, substitutions, locale);Usage Examples:
const Polyglot = require('node-polyglot');
// Basic usage with English
const result1 = Polyglot.transformPhrase(
'You have %{smart_count} messages |||| You have one message',
{ smart_count: 1 },
'en'
);
console.log(result1); // "You have one message"
const result2 = Polyglot.transformPhrase(
'You have %{smart_count} messages |||| You have one message',
{ smart_count: 5 },
'en'
);
console.log(result2); // "You have 5 messages"
// Using number shortcut
const result3 = Polyglot.transformPhrase(
'%{smart_count} items |||| one item',
1,
'en'
);
console.log(result3); // "one item"
// Russian pluralization (3 forms)
const result4 = Polyglot.transformPhrase(
'%{smart_count} товар |||| %{smart_count} товара |||| %{smart_count} товаров',
2,
'ru'
);
console.log(result4); // "2 товара" (uses middle form for 2-4)
// Arabic pluralization (6 forms)
const arabicPhrase = 'zero |||| one |||| two |||| few |||| many |||| other';
const result5 = Polyglot.transformPhrase(arabicPhrase, 2, 'ar');
console.log(result5); // "two" (Arabic has special form for exactly 2)
// Without locale (defaults to 'en')
const result6 = Polyglot.transformPhrase(
'%{smart_count} files |||| one file',
1
);
console.log(result6); // "one file"Phrases with multiple plural forms are separated by |||| (four vertical bars).
// English: 2 forms (singular/plural)
'%{smart_count} items |||| one item'
// Russian: 3 forms (1, 2-4, 5+)
'%{smart_count} товар |||| %{smart_count} товара |||| %{smart_count} товаров'
// Arabic: 6 forms (0, 1, 2, 3-10, 11-99, 100+)
'zero items |||| one item |||| two items |||| few items |||| many items |||| other items'The smart_count option triggers pluralization and provides the count value.
const polyglot = new Polyglot({
phrases: {
'messages': '%{smart_count} messages |||| one message'
}
});
// Different smart_count values
polyglot.t('messages', { smart_count: 0 }); // "0 messages"
polyglot.t('messages', { smart_count: 1 }); // "one message"
polyglot.t('messages', { smart_count: 2 }); // "2 messages"
polyglot.t('messages', { smart_count: 100 }); // "100 messages"
// Number shortcut (equivalent to { smart_count: n })
polyglot.t('messages', 0); // "0 messages"
polyglot.t('messages', 1); // "one message"
polyglot.t('messages', 2); // "2 messages"Built-in pluralization rules for multiple language families:
/**
* Supported plural types with their language mappings
*/
interface DefaultPluralRules {
pluralTypes: {
/** Arabic: 6 forms (0, 1, 2, few, many, other) */
arabic: (n: number) => number;
/** Bosnian/Serbian: 3 forms like Russian */
bosnian_serbian: (n: number) => number;
/** Chinese/Japanese/Korean: 1 form (no pluralization) */
chinese: (n: number) => number;
/** Croatian: 3 forms like Russian */
croatian: (n: number) => number;
/** French: 2 forms (1 vs 2+) */
french: (n: number) => number;
/** German/English: 2 forms (1 vs other) */
german: (n: number) => number;
/** Russian: 3 forms (1, 2-4, 5+) */
russian: (n: number) => number;
/** Lithuanian: 3 forms with special rules */
lithuanian: (n: number) => number;
/** Czech/Slovak: 3 forms (1, 2-4, 5+) */
czech: (n: number) => number;
/** Polish: 3 forms with complex rules */
polish: (n: number) => number;
/** Icelandic: 2 forms with special rules */
icelandic: (n: number) => number;
/** Slovenian: 4 forms (1, 2, 3-4, 5+) */
slovenian: (n: number) => number;
/** Romanian: 3 forms (1, 0 or 2-19, 20+) */
romanian: (n: number) => number;
/** Ukrainian: 3 forms like Russian */
ukrainian: (n: number) => number;
};
pluralTypeToLanguages: {
arabic: ['ar'];
bosnian_serbian: ['bs-Latn-BA', 'bs-Cyrl-BA', 'srl-RS', 'sr-RS'];
chinese: ['id', 'id-ID', 'ja', 'ko', 'ko-KR', 'lo', 'ms', 'th', 'th-TH', 'zh'];
croatian: ['hr', 'hr-HR'];
german: ['fa', 'da', 'de', 'en', 'es', 'fi', 'el', 'he', 'hi-IN', 'hu', 'hu-HU', 'it', 'nl', 'no', 'pt', 'sv', 'tr'];
french: ['fr', 'tl', 'pt-br'];
russian: ['ru', 'ru-RU'];
lithuanian: ['lt'];
czech: ['cs', 'cs-CZ', 'sk'];
polish: ['pl'];
icelandic: ['is', 'mk'];
slovenian: ['sl-SL'];
romanian: ['ro'];
ukrainian: ['uk', 'ua'];
};
}const Polyglot = require('node-polyglot');
// Russian (3 forms)
const ruPolyglot = new Polyglot({
phrases: {
'files': '%{smart_count} файл |||| %{smart_count} файла |||| %{smart_count} файлов'
},
locale: 'ru'
});
ruPolyglot.t('files', 1); // "1 файл" (ends in 1, not 11)
ruPolyglot.t('files', 2); // "2 файла" (2-4, not 12-14)
ruPolyglot.t('files', 5); // "5 файлов" (5+ or 11-14)
// French (2 forms: 1 vs 2+)
const frPolyglot = new Polyglot({
phrases: {
'items': '%{smart_count} élément |||| %{smart_count} éléments'
},
locale: 'fr'
});
frPolyglot.t('items', 1); // "1 élément"
frPolyglot.t('items', 2); // "2 éléments"
// Chinese (no pluralization)
const zhPolyglot = new Polyglot({
phrases: {
'books': '%{smart_count} 本书' // Only one form needed
},
locale: 'zh'
});
zhPolyglot.t('books', 1); // "1 本书"
zhPolyglot.t('books', 5); // "5 本书"
// Arabic (6 forms)
const arPolyglot = new Polyglot({
phrases: {
'days': 'لا أيام |||| يوم واحد |||| يومان |||| %{smart_count} أيام |||| %{smart_count} يوم |||| %{smart_count} يوم'
},
locale: 'ar'
});
arPolyglot.t('days', 0); // "لا أيام" (zero)
arPolyglot.t('days', 1); // "يوم واحد" (one)
arPolyglot.t('days', 2); // "يومان" (two)
arPolyglot.t('days', 5); // "5 أيام" (few: 3-10)You can provide custom pluralization rules when creating a Polyglot instance.
/**
* Custom plural rules structure
*/
interface CustomPluralRules {
pluralTypes: {
[typeName: string]: (count: number) => number;
};
pluralTypeToLanguages: {
[typeName: string]: string[];
};
}Usage Example:
// Custom rule for a fictional language with 4 forms
const customRules = {
pluralTypes: {
fictional: function(n) {
if (n === 0) return 0; // zero form
if (n === 1) return 1; // singular form
if (n <= 10) return 2; // few form (2-10)
return 3; // many form (11+)
}
},
pluralTypeToLanguages: {
fictional: ['fic']
}
};
const polyglot = new Polyglot({
phrases: {
'widgets': 'no widgets |||| one widget |||| %{smart_count} widgets |||| many widgets'
},
locale: 'fic',
pluralRules: customRules
});
polyglot.t('widgets', 0); // "no widgets"
polyglot.t('widgets', 1); // "one widget"
polyglot.t('widgets', 5); // "5 widgets"
polyglot.t('widgets', 15); // "many widgets"