Documentation:
There is a nice tutorial in this blog post. Check it out!
Translation features
with default namespace
// given resourcefile translation.en.json
{
key1: 'value of key 1'
}
i18n.t("key1"); // -> value of key 1
with namespaces set
// given resourcesfile namespace1.en.json (default ns)
{
key1: 'value of key 1'
}
// given additional resourcesfile namespace2.en.json
{
keys: {
2: 'value of key 2',
3: 'value of key 3'
}
}
i18n.t("key1"); // -> value of key 1
i18n.t("namespace1.key1"); // -> value of key 1
i18n.t("keys.2"); // -> missing key
i18n.t("namespace2:keys.2"); // -> value of key 2
i18n.t("namespace2:keys.3"); // -> value of key 3
using multiple keys (first found will be translated)
// given resourcefile translation.en.json
{
key1: 'value of key 1'
}
i18n.t(["notExists", "key1"]); // -> value of key 1
why this might be useful for you too: see discussion
Hint: You can change namespace and/or key separator by setting options on init:
- nsseparator = ':::'
- keyseparator = '::'
i18n.t("namespace2:::keys::2"); // -> value of key 2
multiline in json
// given resources in arabic
{
'en-US': {
translation: {
key: [
"line1",
"line2",
"line3"
]
}
}
};
The translation will be joined with '\n'.
Hint: This might be useful in combination with post processing.
arrays in json
// given resources in arabic
{
'en-US': {
translation: {
people: [
{ name: "tom" },
{ name: "steve" }
]
}
}
};
i18n.t("key.0.name"); // -> tom
providing a default value
// given resources
{
'en-US': { translation: { // key not found } }
};
i18n.t("key", { defaultValue: "my text" }); // -> my text
// or shorter given i18next.init({ shortcutFunction: 'defaultValue' });
i18n.t("key", "my defalut value");
If a resource key isn't resolvable (en-US -> en -> fallbackLng) than normally the key would be returned as string value. You can provide a better default by passing in option defaultValue.
The default value will be send in sendMissing resources, too.
// given resources
{
dev: { translation: { nesting1: '1 $t(nesting2)' } },
en: { translation: { nesting2: '2 $t(nesting3)' } },
'en-US': { translation: { nesting3: '3' } }
};
i18n.t("nesting1"); // -> 1 2 3
Will return '1 2 3'.
All other options like plurals, ... will work as expected
Hint: You can change pre-/suffix by setting options on init:
- reusePrefix = '$t(',
- reuseSuffix = ')',
nested resources with option replace
// given resources
{
en: { translation: {
girlsAndBoys: '$t(girls, {"count": __girls__}) and __count__ boy',
girlsAndBoys_plural: '$t(girls, {"count": __girls__}) and __count__ boys' },
girls: '__count__ girl',
girls_plural: '__count__ girls' } }
};
i18n.t("nesting1", {count: 2, girls: 3}); // -> 3 girls and 2 boys
You could change interpolationPrefix/Suffix (default '__') on need.
// given resources
{
'en-US': { translation: { key: '__myVar__ are important' } }
};
i18n.t("key", { myVar: "variables" }); // -> variables are important
Will return 'variables are important'.
You can even have hierarchical variables in form __some.child__.
Hint 1: You can change pre-/suffix by setting options on init or on calling t function with options:
- interpolationPrefix = '__',
- interpolationSuffix = '__',
Hint 2: You could even have nested values like:
// given resources
{
'en-US': { translation: { key: '__person.name.first__ is important' } }
};
i18n.t("key", { person: { name: { first: 'cristina' } } }); // -> cristina is important
Hint 3: Enscaping:
// given resources
{
'en-US': {
translation: {
key1: Not escaped __nameHTML__,
key2: Escaped __name__
}
}
};
i18n.t("key2", { name: '', escapeInterpolation: true }); // -> Escaped <tag>
i18n.t("key1", { name: '', escapeInterpolation: false }); // -> Not escaped <tag>
Adding suffix 'HTML__' to your value will prevent the escaping even if option is set so.
You could turn on escaping on init i18n.init({escapeInterpolation: true});
or by passing in option to t function like in the sample.
Formating:
numbers or currency: You might try numeraljs.
dates or time: You might try momentjs.
// given resources
{
'en-US': { translation: {
key1: 'The first 4 letters of the english alphabet are: %s, %s, %s and %s',
key2: 'Hello %(users[0].name)s, %(users[1].name)s and %(users[2].name)s'
}}
};
i18n.t("key1", { postProcess: 'sprintf', sprintf: ['a', 'b', 'c', 'd'] });
i18n.t("key2", { postProcess: 'sprintf', sprintf: { users: [{name: 'Dolly'}, {name: 'Molly'}, {name: 'Polly'}] } } );
|
// or simpler given i18next.init({ shortcutFunction: 'sprintf' });
i18n.t("key1", 'a', 'b', 'c', 'd');
For more information about sprintf and source go to dive.into.javascript.
Hint: You can set i18next to always postProcess with sprintf by init with option postProcess: i18n.init({ postProcess: 'sprintf' });
// given resources
{
'en-US': {
translation: {
key: '__count__ child',
key_plural: '__count__ children'
}
}
};
i18n.t("key", { count: 0 }); // -> 0 children
i18n.t("key", { count: 1 }); // -> 1 child
i18n.t("key", { count: 5 }); // -> 5 children
The variable __count__ is optional.
// given resources
{
'en-US': {
translation: {
key: '__count__ child',
key_plural: '__count__ children',
key_indefinite: 'a child',
key_plural_indefinite: 'some children'
}
}
};
i18n.t("key", { count: 1, indefinite_article: true }); // -> a child
i18n.t("key", { count: 5, indefinite_article: true }); // -> some children
i18n.t("key", { count: 0 }); // -> 0 children
i18n.t("key", { count: 1 }); // -> 1 child
i18n.t("key", { count: 5 }); // -> 5 children
Hint: you can set indefiniteSuffix on init to different value.
multiple plural forms
// given resources in arabic
{
'ar': {
translation: {
key: 'singular',
key_plural_0: 'zero',
key_plural_2: 'two',
key_plural_3: 'few',
key_plural_11: 'many',
key_plural_100: 'plural'
}
}
};
i18n.t("key", { count: 0 }); // -> zero
i18n.t("key", { count: 1 }); // -> singular
i18n.t("key", { count: 2 }); // -> two
i18n.t("key", { count: 3 }); // -> few
i18n.t("key", { count: 4 }); // -> few
i18n.t("key", { count: 104 }); // -> few
i18n.t("key", { count: 11 }); // -> many
i18n.t("key", { count: 99 }); // -> many
i18n.t("key", { count: 199 }); // -> many
i18n.t("key", { count: 100 }); // -> plural
What did you expect ;).
Hint: i18next provides the functionality for all languages.
You can override the existing rules via 'i18n.pluralExtension.addRule(lng, obj)'
// sample for arabic
i18n.pluralExtension.addRule("ar", {
"name": "Arabic",
"numbers": [ 0, 1, 2, 3, 11, 100 ],
"plurals": function(n) { return Number(n === 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5); }
});
Definitions can be found here.
// given resources
{
'en-US': {
translation: {
friend: 'A friend',
friend_male: 'A boyfriend',
friend_female: 'A girlfriend'
}
}
};
i18n.t("friend", { count: 0 }); // -> A friend
i18n.t("friend", { context: 'male' }); // -> A boyfriend
i18n.t("friend", { context: 'female' }); // -> A girlfriend
This feature can be combined with plurals.
eg. key: friend_male_plural: '__count__ boyfriends'
return an objectTree
This might be helpful if you need resources for a plugin or library like moment.js.
// given resources
{
'en-US': {
translation: {
tree: { res: 'added' }
}
};
i18n.t("tree", { returnObjectTrees: true }); // -> { res: 'added' }
Hint: All other features (variables, plurals,...) will be applied befor returning tree.
You can turn on this globally by setting the option in i18n.init({ returnObjectTrees: true }).
// given resources
{
'en-US': {
translation: {
state: { on: 'online', off: 'offline' }
}
};
i18n.init({objectTreeKeyHandler: function(key, value, lng, ns, options)
return (app.online) ? i18n.t(key + '.on') : i18n.t(key + '.off')
})
i18n.t("state", { returnObjectTrees: false }); // -> if app.online online else offline
i18n.init({ objectTreeKeyHandler: function(key, value, lng, ns, options) {...} ).
access value in different language
i18n.t("my.key", { lng: "de-DE" }); // -> will get value in de-DE instead of en-US
You should preload the additional languages on init!
Hint: If the additional language wasn't preloaded it will be fetched synchronous.
access value with different fallback language
i18n.t("my.key", { fallbackLng: "de-DE" }); // -> will get value fallbacking to de-DE
check if a key exists
i18n.exists("my.key", options); // same options as in t function
post processing translations
Adding a post processor
eg. add a post processor parsing markdown.
i18n.addPostProcessor("myProcessorsName", function(value, key, options) {
return 'some post processed data based on translated value';
});
Using a post processor on translation
i18n.t("my.key", { postProcess: "myProcessorsName" });
i18next will translate the key as usual. Then it passes the translation text to the post processor.
Hint: Alternatively you can set i18next to always postProcess with a specific postProcessor by init with option postProcess: i18n.init({ postProcess: 'myProcessorsName' });
send missing resources to server
Turn it on:
i18n.init({ sendMissing: true });
All keys unable to resolve will be send to: 'locales/add/dev/translation'
Additional Options:
var options = {
// change path
resPostPath: 'locales/add/__lng__/__ns__',
// change sendType
sendType: 'POST|GET', // default: POST
// send missing values to
sendMissingTo: 'fallback|current|all',
// change async / sync
postAsync: true|false // default: true,
// or override the function
missingKeyHandler: function(lng, ns, key, defaultValue, lngs) { }
}
i18n.init(options);
You can send missing values to the fallbackLng, the current language or all languages (eg. 'en-US', 'en', 'fallback') or replace that function completely.