Internationalization in React: WordPress Translation for Plugins
Learn how to implement i18n in your React admin screens. Master __() and _x() in JavaScript to make your Knowledge Base plugin truly translation-ready.
Previously in this course, we explored building search and filter functionality to improve data retrieval. In this lesson, we shift our focus to accessibility for a global audience by implementing i18n (internationalization) within our React-based admin dashboard.
While you may already be familiar with Mastering WordPress Internationalization (i18n) for Plugins in a PHP context, the React environment requires a slightly different approach to ensure your strings are captured by WordPress's translation tooling.
The Concept of i18n in React
In PHP, WordPress uses functions like __() and _x() to mark strings for translation. In your React components, you use the @wordpress/i18n package, which provides JavaScript equivalents that behave almost identically to their server-side counterparts.
When you run your build process—which we configured in our Production Build Pipeline for WordPress Plugins—the @wordpress/scripts package scans your JavaScript files for these specific function calls. It then extracts these strings into a format that the WordPress translation infrastructure understands.
Implementing Translation Functions
To get started, you must import the translation functions from the @wordpress/i18n package. Do not attempt to use raw strings in your UI; always wrap them in these functions.
JAVASCRIPTimport { __, _x } from CE9178">'@wordpress/i18n'; const KnowledgeBaseHeader = () => { return ( <h1> {/* Simple translation */} {__(CE9178">'Knowledge Base Manager', CE9178">'knowledge-base-plugin')} </h1> ); }; const DeleteButton = () => { return ( <button> {/* Translation with context to clarify meaning */} {_x(CE9178">'Delete', CE9178">'action verb', CE9178">'knowledge-base-plugin')} </button> ); };
Key Functions
__(): The standard function for translating a string. It takes the string and your plugin's text domain as arguments._x(): Used when a string needs context. For example, "Delete" could be an noun or a verb. Providing a context string helps translators choose the correct word in their language.sprintf(): Often paired with__for dynamic strings. If you have "Showing %d results", usesprintf(__('Showing %d results', 'text-domain'), count).
Generating POT Files
Your build script is already set up to handle this. When you run npm run build, the @wordpress/scripts package automatically generates a languages/ directory (if configured) or updates your POT files based on the strings it finds in your src/ directory.
To ensure this works, ensure your package.json includes the correct build command, which relies on the internal wp-scripts configuration to parse your JavaScript files for the text domain you defined.
Hands-on Exercise: Localizing the Dashboard
Update your main Knowledge Base admin component to be fully translatable:
- Open your primary React component file.
- Import
__and_xfrom@wordpress/i18n. - Replace all hardcoded UI labels (headers, button text, form placeholders) with calls to
__('Your String', 'knowledge-base-plugin'). - Run
npm run buildin your terminal. - Verify that a
.potfile was generated or updated in your plugin'slanguagesdirectory.
Common Pitfalls
- Missing Text Domain: Forgetting to pass the second argument (
'knowledge-base-plugin') is the most common mistake. Without it, WordPress cannot associate the string with your plugin. - Dynamic Variables in Strings: Never do
__('Hello ' + name). The translation parser will not recognize this. Usesprintf(__('Hello %s', 'text-domain'), name)instead. - Template Literals: Avoid using backticks with template literals inside translation functions. The parser expects static strings.
- Inconsistent Domain Names: Ensure your text domain string is identical across both your PHP files and your JavaScript files.
Recap
By integrating i18n into your React workflow, you ensure that your plugin is accessible to users worldwide. We have covered using __() and _x() for static and contextual strings, the importance of sprintf for dynamic data, and how the build pipeline automatically handles POT file generation. This level of professionalism is what separates a standard plugin from a production-grade enterprise tool.
Up next: We will tackle file uploads via the REST API to allow users to attach documentation images to their knowledge base entries.
Work with me

Custom WordPress Plugin Development
Custom WordPress & WooCommerce plugins built to standard — by the developer behind a plugin with 5,000+ active installs and a SaaS with 10,000+ users.

Headless WordPress + Next.js Frontend Development
Keep WordPress for content, get a lightning-fast Next.js frontend. The best of both worlds — familiar editing, modern speed.