Working with LinguiJS CLI¶
@lingui/cli
provides the lingui
command for extracting, merging and
compiling message catalogs. Follow setup instructions to install required
packages.
Note
This tutorial assumes you use yarn to run commands. If you use npm, type npm run <command> instead of yarn <command>.
Extracting messages¶
We’re going to use an app we built in a React tutorial. The extract
command looks for messages in the source files and extracts them:
yarn extract
Extracting messages from source files…
Collecting all messages…
Writing message catalogs…
Messages extracted!
Catalog statistics:
┌──────────┬─────────────┬─────────┐
│ Language │ Total count │ Missing │
├──────────┼─────────────┼─────────┤
│ cs │ 40 │ 40 │
│ en │ 40 │ 40 │
└──────────┴─────────────┴─────────┘
(use "yarn extract" to update catalogs with new messages)
(use "yarn compile" to compile catalogs for production)
The message catalog will look like this:
{
"Message Inbox": "",
"See all <0>unread messages</0> or <1>mark them</1> as read.": "",
"{messagesCount, plural, one {There's {messagesCount} message in your inbox.} other {There're {messagesCount} messages in your inbox.}}": "",
"Last login on {lastLogin,date}.": "",
}
It’s in a JSON dictionary, where ‘key’ is message ID and value is an object with some relevant information: translation, defaults and origin for the message.
This catalog is ready for translation. Let’s translate it into Czech by filling the
translation
fields:
{
"Message Inbox": "Přijaté zprávy",
"See all <0>unread messages</0> or <1>mark them</1> as read.": "Zobrazit všechny <0>nepřečtené zprávy</0> nebo je <1>označit</1> jako přečtené.",
"{messagesCount, plural, one {There's {messagesCount} message in your inbox.} other {There're {messagesCount} messages in your inbox.}}": "{messagesCount, plural, one {V příchozí poště je {messagesCount} zpráva.} few {V příchozí poště jsou {messagesCount} zprávy. } other {V příchozí poště je {messagesCount} zpráv.}}",
"Last login on {lastLogin,date}.": "Poslední přihlášení {lastLogin,date}",
}
If we run the extract
command again, we can see in the stats that all
messages are translated:
Catalog statistics:
┌──────────┬─────────────┬─────────┐
│ Language │ Total count │ Missing │
├──────────┼─────────────┼─────────┤
│ cs │ 4 │ 0 │
│ en │ 4 │ 4 │
└──────────┴─────────────┴─────────┘
Messages extracted!
(use "yarn extract" to update catalogs with new messages)
(use "yarn compile" to compile catalogs for production)
extract
merges all translations with new messages, so you can run
this command any time without worrying about losing any translations.
Preparing catalogs for production¶
Once we have all catalogs ready and translated, we can compile the JSON into a
minified JS file with the compile
command. This command parses the
messages in MessageFormat and compiles them into simple functions. It also adds
plural rules to a production ready catalog:
yarn compile
Compiling message catalogs…
Done!
The locale
directory now contains the source catalogs (messages.json
) and
the compiled ones (messages.js
).
Messages added to compiled file are collected in specific order:
Translated message from specified locale
Translated message from fallback locale for specified locale
Translated message from default fallback locale
Message key
It is also possible to merge the translated catalogs into a single file per locale
by specifying catalogsMergePath
. For example if catalogsMergePath
is assigned
locales/{locale}
then catalogs will be compiled to /locales/cs.js
and
/locales/en.js
.
Cleaning up obsolete messages¶
By default, the extract
command merges messages extracted from source
files with the existing message catalogs. This is safe as we won’t accidentally lose
translated messages.
However, sooner or later some messages will be removed from the source. We can
use the --clean
option to clean up our message catalogs:
yarn extract --clean
Validation of message catalogs¶
It might be useful to check if all messages were translated (e.g: in a
continous integration runner). The compile
command has a --strict
option, which does exactly that.
The example output might look like this:
yarn compile --strict
Compiling message catalogs…
Error: Failed to compile catalog for locale en!
Missing 42 translation(s)
Configuring source locale¶
We see that checking for missing translations has one drawback – English message catalog doesn’t require any translations because we’re using English in our source code!
Let’s fix it by setting sourceLocale
in package.json
:
{
"lingui": {
"sourceLocale": "en"
}
}
Running lingui extract
again shows the correct statistics:
Catalog statistics:
┌─────────────┬─────────────┬─────────┐
│ Language │ Total count │ Missing │
├─────────────┼─────────────┼─────────┤
│ cs │ 4 │ 0 │
│ en (source) │ 4 │ - │
└─────────────┴─────────────┴─────────┘
And compilation in strict mode no longer throws an error:
yarn compile --strict
Compiling message catalogs…
Done!
If you use natural language for message IDs (that’s the default),
set sourceLocale
. You shouldn’t use this config if you’re using custom
IDs (e.g: Component.title
).
Pseudolocalization¶
There is built in support for pseudolocalization <https://en.wikipedia.org/wiki/Pseudolocalization>. Pseudolocalization is a method for testing the internationalization aspects of your application by replacing your strings with altered versions and maintaining string readability. It also makes hard coded strings and improperly concatenated strings easy to spot so that they can be properly localized.
Example: Ţĥĩś ţēxţ ĩś ƥśēũďōĺōćàĺĩźēď
To setup pseudolocalization add pseudoLocale
in package.json
:
{
"lingui": {
"pseudoLocale": "pseudo-LOCALE"
}
}
pseudoLocale
option can be any string
examples: en-PL
, pseudo-LOCALE
, pseudolocalization
or en-UK
PseudoLocale string have to be in locales
config as well. Otherwise no folder is going to be created.
Pseudolocalized text is created on yarn compile
command.
The pseudolocalization is automatically created on yarn extract
from messages in order specified in Preparing catalogs for production.
How to switch your browser into specified pseudoLocale¶
We can use browsers settings or extensions. Extensions allow to use any locale.
Browsers are usually limited into valid language tags (BCP 47).
In that case, the locale for pseudolocalization has to be standard locale,
which is not used in your application for example zu_ZA
Zulu - SOUTH AFRICA
Chrome: a) With extension (any string) - https://chrome.google.com/webstore/detail/quick-language-switcher/pmjbhfmaphnpbehdanbjphdcniaelfie b) Without extension - chrome://settings/?search=languages
Firefox: a) With extension (any string) - https://addons.mozilla.org/en-GB/firefox/addon/quick-accept-language-switc/?src=search b) Without extension - about:preferences#general > Language
Catalogs in VCS and CI¶
The locale/_build
folder and locale/*/*.js
(compiled catalogs) are safe to be ignored by your VCS.
What you do need to keep in VCS are the json files (locale/*/*.json
) that contain the messages
for translators. The JavaScript functions that return the actual translations when your app runs in
production are created from those json files. See
Excluding build files guide for more info.
If you’re using a CI, it is a good idea to add the yarn extract
and yarn compile
commands to your build process.
Further reading¶
That’s it! Checkout CLI reference documentation for more
info about lingui
commands or configuration reference
for info about configuration parameters.