I am struggling to load translation in JavaScript for my simple plugin. Translation works for PHP, but not in JS. What seems to be the problem, how can I debug this?

  1. I have loaded text domain in my plugin method and this works ok. My text domain is instantsearch, locale for my language is hr

    load_plugin_textdomain('instantsearch', FALSE, basename( dirname( __FILE__ ) ) . '/languages/'); // returns true
    var_dump(__('No results', 'instantsearch')); // This shows correct translation for my language
    
  2. I have generated .json file with WP CLI

    wp i18n make-json languages/
    
  3. This gives me new file /myplugin/languages/instantsearch-hr-hash.json. My JS file is assets/instant-search.js and somewhere I have read that I need to manually rename that hash. I just copied that file two times and renamed them to the following just to try it out, so something out of those 3 should be working 🙂

    instantsearch-hr-47626afcca1bc179bc9eedb6abdc01ff.json
    instantsearch-hr-instant-search.json
    instantsearch-hr-instantsearch.json
    
  4. I have registered the script for translation

    wp_register_script('instant-search', plugins_url('assets/instant-search.js', __FILE__), array('jquery', 'wp-i18n'), false, true);
    wp_enqueue_script('instant-search');
    wp_set_script_translations('instant-search', 'instantsearch', plugins_url('languages', __FILE__));
    
  5. In the script at the very top I have tried this, but it doesn’t give me translation like in PHP, it just shows english default string

    console.log(wp.i18n.__('No results', 'instantsearch'));
    
  6. Here is example of json

    {"translation-revision-date":"2019-12-31 13:41+0100","generator":"WP-CLI\/2.4.0","source":"assets\/instant-search.js","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","lang":"hr","plural-forms":"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);"},"No results":["Nema prona\u0111enih rezultata"]}}}
    
  7. I know I can use wp_localize_script() to move string from PHP to JS but from WP 5.* we should be able to do it

3 Answers
3

I was having the same problem and this is how I solved it:

First, the generated JSON file has some errors. You need to update where it says messages with your text domain. There are three places where that needs to be changed. I also had to change the lang attribute to be all lowercase with a dash. Here are the fields I changed:

{
  "domain": "my-text-domain",
  "locale_data": {
    "my-text-domain": { // Instead of "messages"
      "": {
        "domain": "my-text-domain",
        "lang": "es-es"
      },
      ...
    }
  }
}

Second, the file name with the md5 hash tends to have the wrong md5 hash, so it’s best to rename the file to {domain}-{locale}-{script-name}.json, so mine became my-text-domain-es_ES-my-script-name.js.

Third, the wp_set_script_translations function needs to be called with the right path, and attached to the right hook. This is what I had to do, since I was localizing an admin-side script:

function enqueue_scripts() {
    wp_set_script_translations( 'script-name', 'my-text-domain', plugin_dir_path( dirname(__FILE__) ) . 'languages' );
}
add_action( 'admin_enqueue_scripts', 'enqueue_scripts' );

Try echoing out the value of plugin_dir_path( dirname(__FILE__) ) . 'languages' to make sure you’re getting the path where your translation files are.

Once I sorted out all of these little details, my translations started working, so I hope this helps someone else!

Leave a Reply

Your email address will not be published. Required fields are marked *