How to Translate a Custom Gutenberg Block
In this lesson, you will learn not only how to translate any Gutenberg block to a specific language properly but also how to prepare your custom block for translation (this process is called internationalization).
Sorry, but you don’t have access to this video lesson.
Sign in to your account or get the course.
In the video above, we will continue working with our “subscription form” block, which we’re creating throughout this course.
At first, I will show you how to configure the block.json file of the Gutenberg block and how to use the internationalization package @wordpress/i18n. After that, we will dive into creating the translation files for, let’s say, the Spanish language.
However, if for some reason, you can not watch this video right now, you can find a short process description below as well.
Part 1. Internationalization of a Gutenberg Block
If you’re translating a ready Gutenberg block, then you can probably start with the second part.
Add textdomain to block.json
It is absolutely the same thing when you develop a plugin for WordPress. Do you remember that you need to provide a textdomain parameter in your plugin metadata?
The same is here; you need to add textdomain to your block.json file:
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
...
"textdomain": "misha-block"
}Import i18n package in the JavaScript file and replace the strings with the translation functions
The i18n package should already be installed and available for you if you used @wordpress/scripts or @wordpress/create-block for your developer environment setup. Otherwise, you would probably need to install it manually with the following NPM command: npm install @wordpress/i18n --save.
After that, let’s import translation functions at the beginning of your edit.js or save.js files:
import { __ } from '@wordpress/i18n';Then, for example, when we display the block settings, we need to do the following replacements in the JSX code:
<InspectorControls>
<PanelBody title={ __( 'Custom settings', 'misha-block' ) }>
<TextControl
label={ __( 'Email placeholder text', 'misha-block' ) }
value={ attributes.placeholder }
onChange={ ( placeholder ) => setAttributes( { placeholder } ) }
/>
<ToggleControl
label={ __( 'Display form image', 'misha-block' ) }
checked={ attributes.showImg }
onChange={ () => setAttributes( { showImg : ! attributes.showImg } ) }
/>
</PanelBody>
<PanelBody title={ __( 'Panel 2', 'misha-block' ) }>
{ __( 'No settings over here', 'misha-block' ) }
</PanelBody>
</InspectorControls>More translation functions are available; for example, below is the list:
| Function name | Function description |
|---|---|
__() | The basic translation function. |
_x() | It can provide a context for a translation. |
_n | For plurals. |
_nx() | For plurals with a context. |
sprintf() | Not exactly a translation function, but it will help you work with plurals. The example is below. |
Of course, don’t forget to import all of them first:
import { __, _x, _n, _nx, sprintf } from '@wordpress/i18n';Below is an example of using the _n() function for plurals:
let num = 5;
sprintf( _n( '%d product', '%d products', num, 'misha-block' ), num );I will also show you how to prepare for translations and to translate block attributes’ default values in the video above.
wp_set_script_translations
As you remember, when you translate a regular WordPress plugin, you need to use the load_plugin_textdomain() function. Does your custom Gutenberg block come as a plugin? Then you need to use it here as well.
However, there is one more function, which is needed for JavaScript string translations; this function is wp_set_script_translations().
The complete snippet with these two functions may look like this:
add_action( 'init', function() {
$textdomain = 'misha-block';
load_plugin_textdomain( $textdomain, false, __DIR__ . '/languages' );
$block_name = 'rudr-subscribe-form';
wp_set_script_translations( $block_name . '-editor-script', $textdomain, __DIR__ . '/languages/' );
} );Probably, it is not 100% clear what $block_name variable is. Easy, I can explain, it is the full block name with its namespace. For example, our example block has the namespace rudr and the block slug subscribe-form. As a result, we need to use the first function parameter value equal to rudr-subscribe-form-editor-script.
By this moment, we’re pretty much done with the Gutenberg block internationalization (preparing it for translations), now let’s dive into the actual translation process.
Part 2. Translating a Gutenberg Block
To translate a Gutenberg block, we will need to create a bunch of files for that:
.pot,.po,.mofiles – as usual, we used these types of files as well, when translating plugins developed with PHP only,.json– this one is needed for JavaScript translations.
The cool thing here is that we can use the i18n package to generate some of them from the command line:
wp i18n make-pot– to generate a POT file,wp i18n make-json– to generate a JSON file.
For convenience, we usually add these commands with the parameters we need to the package.json file. I will show you how to do that in the video above.
All the translations we are doing in Poedit:

Again, I describe the whole process in the video above. You can also download the source files of the translated block below:
Misha Rudrastyh
Hey guys and welcome to my website. For more than 15 years I've been doing my best to share with you some superb WordPress guides and tips for free.
Need some developer help? Contact me