React Plugin Settings Page Localization

adds an admin menu page with a div that React replaces, but the
localization inside this React doesn’t work

Actually, since you are enqueueing the same script (build/index.js), which is automatically registered by register_block_type(), then in your my_enqueue_admin_scripts() function, just do wp_enqueue_script( 'my-block-local-editor-script' ) to enqueue/load the script on your admin menu page.

And secondly, change the add_action('enqueue_block_editor_assets', 'script_translations') to add_action('admin_enqueue_scripts', 'script_translations'), i.e. use the admin_enqueue_scripts action instead to set the script translations. That way, the translations would be loaded both on your custom admin page and core admin pages where the block-based editor is used, e.g. the post editing screen at wp-admin/post.php.

However, I suggest you to use a separate JS file for your admin page’s (React) code, and manually call wp_set_script_translations() after you enqueued your script, e.g.

$asset = include plugin_dir_path( __FILE__ ) . 'build/settings-page.asset.php';

wp_enqueue_script(
    'my-settings-page',
    plugin_dir_url( __FILE__ ) . 'build/settings-page.js',
    $asset['dependencies'],
    $asset['version'],
    true
);

wp_set_script_translations(
    'my-settings-page', // script handle
    'my-block',         // text domain
    plugin_dir_path( __FILE__ ) . 'languages'
);
  • Note: With the above example, WordPress will try to find the JSON translations file at languages/<text domain>-<locale>-<script handle>.json in your plugin folder, e.g. languages/my-block-es_ES-my-settings-page.json for the Español locale.

    If not found, WordPress will try to find the file at languages/<text domain>-<locale>-<MD5 hash of the relative file path>.json, e.g. languages/my-block-es_ES-3e9997d5fc8385c27402b8531ec46c31.json for the Español locale. ( md5( 'build/settings-page.js' ) equals 3e9997d5fc8385c27402b8531ec46c31 )

  • You can see my scripts here and the above example is the actual code I used in my sample plugin.