JavaScript i18n support in Loco Translate
Version 2.5 added support for JSON translation files used in WordPress >= 5.
Quick introduction
Most WordPress language packs consist of pairs of PO and MO files. The PO file is what you edit within a file editor like Loco Translate. The MO file is a binary format compiled from the PO file. This is what WordPress actually reads in order to load translations into PHP.
In order to load translations into JavaScript developers can simply pass translations from PHP into a web page. Historically this has been done with wp_localize_script, although there are many ways to achieve the same result and many ways for developers to handle the strings in their JavaScript code.
However, WordPress 5 added wp_set_script_translations which provides developers with a common JavaScript localization library bundled into WordPress. Instead of passing translations into JavaScript from PHP, the new method loads translations directly from separate JSON files.
We won't replicate the WordPress documentation on this topic, see JavaScript i18n support in WordPress 5.0 and follow the links to relevant information.
Compiling JSON translation files
Every time you save a PO file in Loco Translate, any translations used in JavaScript will be extracted into JSON files according to WordPress naming conventions. This process relies on file references within the PO file pointing to a valid JavaScript file. The approach is identical to that used by wp i18n make-json.
You will find the JSON files have curious names and there may be many of them. This is because a JSON file is compiled for every separate script. For example, take a PO file (fr_FR.po
) containing the following message:
#: scripts/example.js:21
msgid "Hello World"
msgstr "Bonjour tout le Monde"
Saving this file in Loco Translate would generate a JSON file called my-plugin-fr_FR-72e8c5e24e35642471d54763afbb6a54.json
where the long string is computed as md5("scripts/example.js")
.
Its contents will contain only the strings associated with the given script. This file should be treated the same way you treat MO files: It must be deployed to your website in order for WordPress to read it, but it is not for editing directly. It can always be recompiled from the PO file if it gets lost.
There are two new options in the Loco Translate plugin settings to accompany this function.
Extracting JavaScript strings
Loco Translate has some capability to generate POT files from JavaScript, but authors are recommended to use wp i18n make-pot
and ship a valid and up to date POT file with their code.
Whichever tool you use, it's preferable to extract strings from unminified JavaScript as this gives a more useful file reference and line number.
However, be aware that WordPress supports only basic mapping of .js
to .min.js
files when computing the JSON file names. More complex build systems may cause you issues. See the notes below.
If you need to translate someone else's JavaScript strings without a POT file, try following our advice on missing templates. In all cases (JavaScript or otherwise) we recommend against translators generating their own templates. See our help pages on working with POT files and extracting translatable strings.
Notes and caveats
Source references in the PO file must be valid relative paths and exist in the deployed code. If both the
.js
and the.min.js
files are missing then no JSON will be generated for the script. This is to avoid filling up folders with JSON files that will never be loaded. See String extraction for more detail on this.Loading script translations from Loco Translate's custom directory works identically to MO files in that they are merged. This merging is done in PHP which means the JSON is decoded and encoded. This solution is not ideal, but currently the most reliable method we've come up with.
Be aware that WordPress does not verify JSON files and will print them directly into JavaScript without any sanitation. This means script translations should be treated as trusted code. Don't install JSON translations from an untrusted source without checking them. If they contain executable JavaScript, it will run in the browser.
Do not use
wp i18n make-json
to save JSON files into Loco Translate's custom directory. It's essential for correct merging that JSON files exclude empty keys like MO files do. Our compiler does this; WP-CLI does not.If you do use
wp i18n make-json
, always specify--no-purge
because this command purges by default. JSON files are not directly editable in Loco Translate, so if you strip script translations from a PO file then you'll no longer be able to edit them. Furthermore, if you were to lose the JSON file, there would be no way to recover the translations except from a backup.WordPress gives priority to authors' own JSON files if they are named according the script handle, e.g.
myDomain-fr_FR-myScript.json
and will not look any further if it finds one. Loco Translate cannot generate JSON files with this naming convention. Authors can choose any unique handle they like and there is no way to derive this from a POT file.Be aware that language packs installed by WordPress will have script translations purged from the PO and MO files. Strings used only in
.js
files will be present only in the JSON files. As of Loco Translate 2.5.3 you can choose to merge JSON strings when you copy a PO file, however the JSON format is such that important PO metadata may be lost.Loco Translate derives JSON file names from the file references held in PO files when they are saved. This name must match the one that WordPress derives from the related script when it is loaded by your theme or plugin. There are many reasons this can fail.