This is an implementation of ngettext function from standard GNU gettext. But also its standard behavior can be extended by some extra configuration for handling different number of plural forms than 2. By default it works as expected with 2 plural forms. So you can use it even when you don't have actual translations, just for having support for plural forms in your code.

Live demo

this demo works without the transpilation step, consider using babel-plugin-ttag for production usage


import { ngettext, msgid } from 'ttag'

function test(n) {
    return ngettext(msgid`${n} time clicked`, `${n} times clicked`, n)

This example works out of the box without no extra configuration for ttag plugin.

You may noticed that the first argument for ngettext is tagged with msgid tag. This may seem a little bit weird, but this is the only way to find translations by msgid without code transpilation with babel plugin. User friendly checks on extract and resolve steps will not let you forgive about that. More details about why we are using msgid tag are here.

ngettext format


ngettext(msgid`${n} time clicked`, `${n} times clicked`, n)
ngettext(msgid`${1} time clicked`, `${1} times clicked`, 1)
ngettext(msgid`${this.count} time clicked`, `${this.count} times clicked`, this.count)


ngettext(msgid`${n} time clicked`, `${n} times clicked`) // plural number argument is missing
ngettext(`${n} time clicked`, `${n} times clicked`, n) // msgid tag for the first argument is missing
// only identifiers and member expressions are allowed inside translated templates.
ngettext(msgid`${fn()} time clicked`, `${fn()} times clicked`, fn())

.po extraction

We will extract this from the example above:

#: src/ngettextDemo.js:19
msgid "${ n } time clicked"
msgid_plural "${ n } times clicked"
msgstr[0] ""
msgstr[1] ""

Resolve translations

Assume that translator added translations to our previous extracted entry:

#: src/ngettextDemo.js:19
msgid "${ n } time clicked"
msgid_plural "${ n } times clicked"
msgstr[0] "${ n } time clicked [translated]"
msgstr[1] "${ n } times clicked [translated]"

The resulting code (after transpilation will look like):

"use strict";
function _tag_ngettext(n, args) { 
    return args[+(n != 1)];

function test() {
    return _tag_ngettext(n, [ n + " time clicked [translated]", n + " times clicked [translated]" ]));

There is a new extra function in our file - _tag_ngettext, but you don't need to worry much about it, because this function is autogenerated by ttag and may change in future without requiring any changes to your code.

Plural forms that are different from default (English)

It is possible that your are using different language than English in strings in the sources. And here is the point when usage of ngettext becomes not so clear. For instance, you decided to write strings in Ukrainian, because at the time of the first release it was a single language for your project. At some point, you decided to localize your strings and want to use ngettext for plurals. Ukrainian language has 3 plural forms, but standard ngettext has only 2 arguments for them, so which one of those 3 plural forms must be passed to ngettext function? ttag suggests a quite a nice solution for this problem.

By default ttag uses 'en' language (English), but if you want to use ngettext with Ukrainian locale, you should call setDefaultLang for the library and defaultLang for the plugin accordingly.


// 3 forms will be extracted
ngettext(msgid`${ n }form1`, `${ n } form2`, `${ n } form3`, n);

Tip: you can check the official GNU gettext manual for language ISO codes.

results matching ""

    No results matching ""