I18N in the Multiverse of Formats

I18N in the Multiverse of Formats

Clarification

i18next

  • I would like to eat a cake.
  • I would like to eat 3 muffins.
  • I would like to eat something.
{
"dessert_cake_one": "I would like to eat a cake.",
"dessert_muffin_one": "I would like to eat a muffin.",
"dessert_cake_other": "I would like to eat {{count}} cakes.",
"dessert_muffin_other": "I would like to eat {{count}} muffins.",
"dessert": "I would like to eat something."
}
i18next.t('dessert', { context: 'cake', count: 1 }) // -> "I would like to eat a cake."
i18next.t('dessert', { context: 'muffin', count: 1 }) // -> "I would like to eat a muffin."
i18next.t('dessert', { context: 'cake', count: 5 }) // -> "I would like to eat 5 cakes."
i18next.t('dessert', { context: 'muffin', count: 5 }) // -> "I would like to eat 5 muffins."
i18next.t('dessert') // -> "I would like to eat something."
{
"dessert_cake_zero": "I would like to eat no cake.",
"dessert_muffin_zero": "I would like to eat no muffin.",
"dessert_cake_one": "I would like to eat a cake.",
"dessert_muffin_one": "I would like to eat a muffin.",
"dessert_cake_two": "I would like to eat two cakes.",
"dessert_muffin_two": "I would like to eat two muffins.",
"dessert_cake_few": "I would like to eat a few cakes.",
"dessert_muffin_few": "I would like to eat a few muffins.",
"dessert_cake_many": "I would like to eat many cakes.",
"dessert_muffin_many": "I would like to eat many muffins.",
"dessert_cake_other": "I would like to eat {{count}} cakes.",
"dessert_muffin_other": "I would like to eat {{count}} muffins.",
"dessert": "I would like to eat something."
}
i18next.t('dessert', { context: 'cake', count: 1 }) // -> "I would like to eat a cake."
i18next.t('dessert', { context: 'muffin', count: 2 }) // -> "I would like to eat two muffins."
i18next.t('dessert', { context: 'cake', count: 5 }) // -> "I would like to eat a few cakes."
i18next.t('dessert', { context: 'muffin', count: 13 }) // -> "I would like to eat many muffins."
i18next.t('dessert', { context: 'cake', count: 100 }) // -> "I would like to eat 100 cakes."
i18next.t('dessert') // -> "I would like to eat something."
{
"eat": "I would like to eat",
"dessert_cake_one": "$t(eat) a cake.",
"dessert_muffin_one": "$t(eat) a muffin.",
"dessert_cake_other": "$t(eat) {{count}} cakes.",
"dessert_muffin_other": "$t(eat) {{count}} muffins.",
"dessert": "$t(eat) something."
}

ICU Message Format

import { createIntl } from '@formatjs/intl'const intl = createIntl({
locale: 'en',
messages: {
dessert: `I would like to eat {what, select,
cake {{count, plural,
one {a cake}
other {{count} cakes}
}}
muffin {{count, plural,
one {a muffin}
other {{count} muffins}
}}
other {something}
}.`,
},
})
intl.formatMessage({ id: 'dessert' }, { what: 'cake', count: 1 }) // -> "I would like to eat a cake."
intl.formatMessage({ id: 'dessert' }, { what: 'muffin', count: 1 }) // -> "I would like to eat a muffin."
intl.formatMessage({ id: 'dessert' }, { what: 'cake', count: 5 }) // -> "I would like to eat 5 cakes."
intl.formatMessage({ id: 'dessert' }, { what: 'muffin', count: 5 }) // -> "I would like to eat 5 muffins."
intl.formatMessage({ id: 'dessert' }, { what: undefined }) // -> "I would like to eat something."

vue-i18n

import { createI18n } from 'vue-i18n'const i18n = createI18n({
fallbackLocale: 'en',
messages: {
en: {
dessert_cake: 'I would like to eat a cake. | I would like to eat {count} cakes.',
dessert_muffin: 'I would like to eat a muffin. | I would like to eat {count} muffins.',
dessert: 'I would like to eat something.'
}
}
})
$t('dessert_cake', { count: 1 }) // -> "I would like to eat a cake."
$t('dessert_muffin', { count: 1 }) // -> "I would like to eat a muffin."
$t('dessert_cake', { count: 5 }) // -> "I would like to eat 5 cakes."
$t('dessert_muffin', { count: 5 }) // -> "I would like to eat 5 muffins."
$t('dessert') // -> "I would like to eat something."

i18n-js

{
"dessert_cake": {
"one": "I would like to eat a cake.",
"other": "I would like to eat %{count} cakes."
},
"dessert_muffin": {
"one": "I would like to eat a muffin.",
"other": "I would like to eat %{count} muffins."
},
"dessert": "I would like to eat something."
}
i18n.t('dessert_cake', { count: 1 }); // -> "I would like to eat a cake."
i18n.t('dessert_muffin', { count: 1 }); // -> "I would like to eat a muffin."
i18n.t('dessert_cake', { count: 5 }); // -> "I would like to eat 5 cakes."
i18n.t('dessert_muffin', { count: 5 }); // -> "I would like to eat 5 muffins."
i18n.t('dessert'); // -> "I would like to eat something."

Polyglot.js

{
"dessert_cake": "I would like to eat a cake. |||| I would like to eat %{smart_count} cakes.",
"dessert_muffin": "I would like to eat a muffin. |||| I would like to eat %{smart_count} muffins.",
"dessert": "I would like to eat something."
}
polyglot.t('dessert_cake', { smart_count: 1 }) // -> "I would like to eat a cake."
polyglot.t('dessert_muffin', { smart_count: 1 }) // -> "I would like to eat a muffin."
polyglot.t('dessert_cake', { smart_count: 5 }) // -> "I would like to eat 5 cakes."
polyglot.t('dessert_muffin', { smart_count: 5 }) // -> "I would like to eat 5 muffins."
polyglot.t('dessert') // -> "I would like to eat something."

Gettext

msgid ""
msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"lang: en\n"
"plural_forms: nplurals=2; plural=(n != 1);\n"
#:
msgid "dessert"
msgstr "I would like to eat something."
#:
msgctxt "cake"
msgid "dessert"
msgid_plural "I would like to eat %d cakes."
msgstr[0] "I would like to eat a cake."
msgstr[1] "I would like to eat %d cakes."
#:
msgctxt "muffin"
msgid "dessert"
msgid_plural "I would like to eat %d muffins."
msgstr[0] "I would like to eat a muffin."
msgstr[1] "I would like to eat %d muffins."
const i18n = new Jed({
locale_data: {
messages: {
"": {
domain: "messages",
lang: "en",
plural_forms: "nplurals=2; plural=(n != 1);"
},
"cake\u0004dessert": [
"I would like to eat a cake.",
"I would like to eat %d cakes."
],
"muffin\u0004dessert": [
"I would like to eat a muffin.",
"I would like to eat %d muffins."
],
dessert: ["I would like to eat something."]
}
}
})
i18n.translate('dessert').withContext('cake').fetch() // -> "I would like to eat a cake."
i18n.translate('dessert').withContext('muffin').fetch() // -> "I would like to eat a muffin."
i18n.translate('dessert').withContext('cake').ifPlural(5).fetch(5) // -> "I would like to eat 5 cakes."
i18n.translate('dessert').withContext('muffin').ifPlural(5).fetch(5) // -> "I would like to eat 5 muffins."
i18n.translate('dessert').fetch() // -> "I would like to eat something."

FBT

<fbt desc="eating cake">
I would like to eat
<fbt:plural
count={1}
name="number of cakes"
showCount="ifMany"
many="cakes">
a cake
</fbt:plural>.
</fbt> <!-- "I would like to eat a cake." -->
<fbt desc="eating muffin">
I would like to eat
<fbt:plural
count={5}
name="number of muffins"
showCount="ifMany"
many="muffins">
a muffin
</fbt:plural>.
</fbt> <!-- "I would like to eat 5 muffins." -->
<fbt desc="eating something">
I would like to eat something.
</fbt> <!-- "I would like to eat something." -->
{
"fb-locale": "en",
"translations": {
"bxFNG7FeHhfvzOcxJ4WpXA==": {
"tokens": [],
"translations": [
{
"translation": "I would like to eat {number of cakes} cakes.",
"variations": {}
}
],
"types": []
},
"1kfdpAZKBoeV6P/6/jU9BQ==": {
"tokens": [],
"translations": [
{
"translation": "I would like to eat a cake.",
"variations": {}
}
],
"types": []
},
"Yglr/cfclqA86jmKXJXtjg==": {
"tokens": [],
"translations": [
{
"translation": "I would like to eat {number of muffins} muffins.",
"variations": {}
}
],
"types": []
},
"Ic2KkQ3gBr6AUcgtsH576g==": {
"tokens": [],
"translations": [
{
"translation": "I would like to eat a muffin.",
"variations": {}
}
],
"types": []
},
"r2YYz0TzAkH0b0TSwFMEAw==": {
"tokens": [],
"translations": [
{
"translation": "I would like to eat something.",
"variations": {}
}
],
"types": []
}
}
}

Fluent

import { FluentBundle, FluentResource } from "@fluent/bundle";const resource = new FluentResource(`
dessert =
I would like to eat
{$toEat ->
[cake] {$count ->
[one] a cake
*[other] {$count} cakes
}
[muffin] {$count ->
[one] a muffin
*[other] {$count} muffins
}
*[other] something
}.
`)
const bundle = new FluentBundle('en')
bundle.addResource(resource)
bundle.formatPattern(bundle.getMessage('dessert').value, { toEat: 'cake', count: 1 }) // -> "I would like to eat a cake."
bundle.formatPattern(bundle.getMessage('dessert').value, { toEat: 'muffin', count: 1 }) // -> "I would like to eat a muffin."
bundle.formatPattern(bundle.getMessage('dessert').value, { toEat: 'cake', count: 5 }) // -> "I would like to eat 5 cakes."
bundle.formatPattern(bundle.getMessage('dessert').value, { toEat: 'muffin', count: 5 }) // -> "I would like to eat 5 muffins."
bundle.formatPattern(bundle.getMessage('dessert').value, { toEat: '' }) // -> "I would like to eat something."

Coming back home

portal

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Adriano Raiano

Adriano Raiano

founder of locize.com; Software Architect, Bachelor in Computer Science #serverless #nodejs #cqrs #ddd always in search for #innovative and #disruptive stuff