The internationalisation of my theme is defined in functions.php and the javascript file to be internationalised uses the wp-i18n library. The translation function __('string',text-domain'); is recognised correctly and the default language (fr) is displayed correctly. But the translation is never found by the wp_set_script_translations() function when en_GB language is localeData.

The internationalization works perfectly with php for my custom theme and plugins !Also my custom translation plugin works perfectly with en_GB.

What files is used to read translation : textdomain-loc_ale-md5.json file or textdomain-loc_ale.po and textdomain-loc_ale.mo files ?

wp_set_script_translations(): Is it possible to call wp_set_script_translations() inside functions.php (theme folder)? If yes, does I make a mistake In my code ? Does "init" is the good action hook to use to load wp_set_script_translations() from the theme folder ? I tried to add and move slash to the directory of file.js and languages folder but it's still not working.

json file : Should the -{md5} part of the json file name be kept or can something else be used, from theme folder?

json parameters : What do the elements "domain": "messages" and "locale_data":{"messages":{"":{"domain": "messages","lang":"en_GB",.. in the json file script correspond to or refer to? Should "messages" be replaced by "text-domain"? If yes , how to filled this element directly from Cli-Command and why it's not filled automatically ?

The official documentation of i18n doesn't talk about that.

Theme/script/file.js :

var localeData = $('html').prop('lang');
localeData = localeData.replace('-', '_'); //return en_GB
const { __ } = wp.i18n;
const textdomain = 'text-domain';
__( '__', 'ActivUs' );

Theme/functions.php :

add_filter('locale', 'getnewlocale');
function getnewlocale($locale) {
    $gen_locale = explode('/',$_SERVER["REQUEST_URI"])[1];
     if ( !is_admin() ) {
        $locale = ($gen_locale == 'fr') ? 'fr_FR' : (($gen_locale == 'en') ? 'en_GB' : '' );
        return $locale;

add_action("after_setup_theme", function () {
    load_theme_textdomain( 'text-domain', get_stylesheet_directory() . '/languages' );
}, 5);

add_action( 'init', 'js_load_text_domain' );
function js_load_text_domain() {
    wp_set_script_translations( get_stylesheet_directory() . '/script/file.js', 'text-domain', get_stylesheet_directory() . '/languages/');
// get_stylesheet_directory() . '/languages'

Files in the "Theme/languages" folder :


Example of Theme/languages/en_GB.po file:

#: script/file.js:969
#: script/file.js:2094
msgid "Revenir à la page précédente"
msgstr "Go back to previous page"


All my javascript files from theme folder were called inside header.php and footer.php. To get $handle for my file.js inside theme folder I had to decide to enqueue this one like that :

function actionjs_enqueue_scripts() {
    wp_enqueue_script( 'main-action', get_template_directory_uri() . '/script/file.js', array('jquery', 'wp-i18n' ), '1.0.0', true);
add_action( 'wp_enqueue_scripts', 'actionjs_enqueue_scripts' );

My $handle ("id" of file.js) is 'main-action'.

According to the documentation it seems necessary to call the Hook of wp_set_script_translations() after enqueued script like that (priority = 100):

function load_js_text_domain(){
    wp_set_script_translations( 'main-action', 'text-domain', get_stylesheet_directory().'/languages');
add_action( 'wp_enqueue_scripts', 'load_js_text_domain', 100 );

At the moment I'm not sure of anything as the translation is still not loading.

How can I check that the .json or .po file is being read? Check that the name of the json file is correct? I've tried so many combinations.

I still don't know which file is read for translation. Is it text-domain-en_GB-my-handle.json or en_GB.po?

1-If it's the .json file, do I have to add the translation by hand from the .po file that's already been translated?

2-Why doesn't the make-json command do this automatically (cli-command)? However, I see that the source of .json file is the /script/file.js.

3-Does wp_set_script_translations automatically decode the json or do I have to use json_decode()? This is how a value in the json file looks like :

"Revenir \u00e0 la page pr\u00e9c\u00e9dente":[""]

Must I filled that [""]? If I add ["Go to the previous page"], nothing happens !

1 Answer 1


Good News after 2 days!

I resolved my issue, but I believe that wp i18n make-json does not generate the json file correctly. Why?

Because it uses the ISO codes and not the locale (get_locale()) from the browser/user. So it isn't "en_GB" that should be used but "en" in the .json file.

This :

"locale_data": {"messages": { "lang": "en_GB",...

should be :

"locale_data": {"messages": { "lang": "en",....

That means that you can't distinguish between 'en_US' and 'en_GB'. So it makes no sense to name these files (.po and .json) with the locale (en_GB) if json use only ISO 639 to retrieve used language.

As a reminder : Language_Country (en_GB) correspond to Language[ISO 639]_country[ISO 3166].

I also think it's a pity, even if the documentation specifies it, that wp i18n make-json (Cli Command) should automatically generate the name of the json file based on the files (at least for Wordpress) that already exist and assuming you already have a .pot and .po file.

For example, from these files: Awesome.pot , fr_FR.po, en_GB.pot with "Awesome" as the text-domain, obtain: Awesome-en_GB-md5.json and Awesome-fr_FR-md5.json.

Here the script to use to javascript internationalization for a script from the theme folder:

Theme/script/file.js doesn't change. see in the original question.

Files inside Theme/languages folder doesn't change.

Theme/functions.php :

function actionjs_enqueue_scripts() {
    wp_enqueue_script( 'main-action', get_template_directory_uri() . '/script/action.js', array('jquery', 'wp-i18n' ), '1.0.0', true);
add_action( 'wp_enqueue_scripts', 'actionjs_enqueue_scripts' );

function load_js_text_domain(){
    wp_set_script_translations( 'main-action', 'your-text-domain', get_stylesheet_directory() . '/languages');
add_action( 'wp_enqueue_scripts', 'load_js_text_domain', 100 );

add_action("after_setup_theme", function () {
    load_theme_textdomain( 'your-text-domain', get_stylesheet_directory() . '/languages' );

The script for text-domain-en_GB-md5.json file looks like this :

    "translation-revision-date": "2023-09-14 19:28+0200",
    "generator": "WP-CLI\/2.8.1+infong1.1.2",
    "source": "script\/action.js",
    "domain": "your-text-domain",
    "locale_data": {
        "messages": {
            "": {
                "domain": "your-text-domain",
                "lang": "en", // And not "en_GB", only ISO 639
                "plural-forms": "nplurals=2; plural=(n != 1);"
            "Ville principale": [
                "Main town"

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .