This guide outlines the step-by-step approach to implementing internationalization (i18n) using a modern stack (Bun/npm/yarn/pnpm), Composer, React (via @wordpress/scripts), and a local WP-CLI bundle.
1. Tooling & Dependencies
PHP (Local WP-CLI)
Instead of requiring a global system installation, bundle WP-CLI's translation tools directly in your project:
composer require --dev wp-cli/i18n-command
JavaScript
Install the WordPress i18n utility using your preferred package manager:
# Bun
bun add @wordpress/i18n
# npm
npm install @wordpress/i18n --save
# pnpm
pnpm add @wordpress/i18n
# yarn
yarn add @wordpress/i18n
2. String Wrapping
In React (TSX/JS)
Import the __ function and use your plugin's text domain.
import { __ } from '@wordpress/i18n';
export const MyComponent = () => (
<h1>{__('Hello from React', 'my-plugin-domain')}</h1>
);
In PHP
Use standard WordPress functions.
echo __('Settings', 'my-plugin-domain');
3. Automation Scripts
Add these to your package.json. We use the PHP bootstrapper to ensure the local WP-CLI bundle runs on any environment (Windows, Mac, Linux) without assuming a global binary.
{
"scripts": {
"i18n:make-pot": "php vendor/wp-cli/wp-cli/php/boot-fs.php i18n make-pot . languages/plugin-domain.pot --domain=plugin-domain --exclude=node_modules,vendor,dist",
"i18n:make-json": "php vendor/wp-cli/wp-cli/php/boot-fs.php i18n make-json languages --no-purge"
}
}
4. Runtime Integration
Tell WordPress where to find the JSON translation files for your React application. This is typically done in your Admin or Main plugin class:
add_action('admin_enqueue_scripts', function() {
// ... your script registration ...
wp_set_script_translations(
'my-script-handle', // The handle used in wp_enqueue_script
'my-plugin-domain',
plugin_dir_path( __FILE__ ) . 'languages'
);
});
5. The Production Workflow
Follow these steps whenever strings change:
Build:
-
bun run build(ornpm/yarn/pnpm) -
Why? WP-CLI extracts React strings from the compiled JavaScript in
assets/, not the raw.tsxsource.
Extract:
-
bun run i18n:make-pot(ornpm run ...) - Scan PHP and compiled JS to update the template.
Translate:
- Open
languages/plugin-domain.potin Poedit and save asplugin-domain-{locale}.po(e.g.,productbay-es_ES.po).
Convert:
-
bun run i18n:make-json(ornpm run ...) -
Generate the
.jsonfiles that WordPress loads for the React frontend.
Summary of the Approach
- Source of Truth: The built assets (for React) and PHP source.
-
Portability: Uses
vendor/bin(boot-fs.php) to avoid "it works on my machine" issues. - Efficiency: One command for extraction, one for deployment.
Top comments (0)