VIEW THIS AS

Auto mode follows the Route Engine until you choose a viewpoint.

YOU ARE HERE

ROUTE CHECK

CONNECTED TO

WHAT NEXT

Use the canonical route for this room, or HELP if you are unsure.

How People Translate Quickly | WordPress Plugin Translation QA: PO, MO, JavaScript JSON, Text Domains and Gutenberg Blocks

Three students study around open books and worksheets in a shared classroom.

To translate a WordPress plugin or Gutenberg block quickly, start by confirming that user-facing strings are marked with the correct WordPress internationalization functions and a consistent text domain. Extract the messages into a POT template, translate them in PO files, and generate the runtime translations needed by PHP and JavaScript. Then switch a real WordPress installation to the target language and test the actual plugin screens. A translation is not ready simply because a PO editor says every row has text.

If you are searching for how to translate a WordPress plugin, WordPress PO and MO files, wp i18n make-pot, JavaScript translation JSON, or why Gutenberg block translations are not loading, the most important distinction is between several related but different artifacts. POT is a translation template. PO holds editable source-and-target pairs. MO is a common compiled representation used by gettext-style WordPress translations. Block-editor JavaScript also uses locale-specific JSON files with its own loading and filename rules. Mixing these pieces up can leave part of a plugin translated and the rest in English.

This guide takes you through a practical WordPress localization pipeline covering PHP gettext wrappers, domain names, context, plurals, parameter formatting, escaping, translator notes, POT/PO/MO files, JavaScript JSON generation, script handles, Gutenberg blocks, plugin language packs, locale selection, accessibility and deployment checks. It focuses on the kind of question a developer or translator actually needs answered: what should I change, what must remain stable, and how do I prove the result works?

The fast workflow from source to a translated plugin

Choose five plugin messages to test: a settings label, a confirmation with a dynamic value, a singular/plural count, a Gutenberg block title and a JavaScript-only error. Locate the WordPress translation functions that produce each one and record the text domain. Generate a POT file with WP-CLI or the project’s approved extraction step. Translate a target PO file, generate the appropriate compiled assets and install them where the actual site expects them.

Then choose the target language in a test WordPress installation and open all five real screens. Check whether the words appear in the right language, whether variables are inserted correctly, and whether the actions still work. Test in the site front end and in the block editor when the plugin has both PHP and JavaScript user interfaces. One successfully translated settings page cannot prove that the editor’s JavaScript resources are also loaded.

This sequence prevents the most expensive category of localization mistake: polishing words that never reach the application. When the test fails, check extraction, translation, compiled file, text domain, locale and runtime loading in that order. Each is a separate possible cause with a more precise repair than simply trying another translation.

Identify the plugin’s real text domain

WordPress uses text domains to distinguish strings owned by different plugins and themes. A plugin’s domain should align with its slug according to WordPress developer guidance. In ordinary plugin-directory practice, that means a lowercase hyphenated identifier matching the plugin slug, not a target-language version of the brand or a random per-page label.

A gettext call such as __( ‘Save settings’, ‘my-plugin’ ) does two jobs: it supplies the source-language string and identifies the domain responsible for the translation. If the code uses a mismatched domain, the correct target text may be present in a language file that WordPress never consults for that call. A translation editor cannot repair that mismatch by changing French or Spanish words.

Inspect the plugin header, registered text domain, extraction configuration and translation filenames. Create one canonical domain in a project configuration or development guideline so contributors do not alternate between my-plugin and my_plugin. A static linter can flag translation calls without the correct domain long before the plugin is released.

Understand the Domain Path without assuming it loads everything

Plugin headers may also specify a Domain Path such as /languages. This records where bundled translation files are associated with the plugin. It is useful for WordPress language discovery and packaging, but it should not be confused with a promise that every file under that folder is loaded into both PHP and JavaScript contexts.

WordPress.org-hosted plugins also interact with translated language packs distributed through WordPress systems. The presence and precedence of installed packs can affect which catalog the runtime uses. Modern WordPress installations have language-loading behavior that has evolved over releases, including just-in-time loading. Do not copy an old initialization snippet into a new plugin without checking whether it is still necessary and correctly timed.

Test the actual environment. If the domain and translation exist but the wrong target appears, inspect where the running site found its language data and whether a WordPress.org language pack or bundled file supplied it. Do not assume the last PO file edited is always the one the user sees.

Mark basic PHP strings with WordPress functions

For ordinary PHP-facing text, WordPress provides familiar gettext-style helpers. The __() function retrieves a translation; _e() echoes it. Other helpers provide escaping appropriate to specific HTML contexts. The code should clearly identify the static source phrase and its owning text domain so extraction tools can find it reliably.

Do not build source strings dynamically before passing them to gettext. An expression that concatenates a person’s name or selects part of a sentence before translation can prevent static extractors from finding the full intended message. More importantly, it may force English word order onto another language. Keep a complete localizable sentence with formatting placeholders where dynamic data belongs.

When scanning a project, include strings exposed to the user in forms, configuration panels, alerts, menus, status indicators and server-rendered output. Developer-only identifiers, URLs and CSS class names normally do not need translation. The extraction inventory should distinguish actual reader content from technical strings, rather than wrapping every literal in a translation call.

Retrieve and escape text for the correct output context

WordPress includes functions that combine translation and escaping for common HTML or attribute contexts, such as esc_html__ and esc_attr__. Choosing the right function is part of safe user-interface implementation. A translated string can include punctuation or markup-like characters without intending to become executable HTML.

Avoid outputting unescaped translated data merely because it came from a trusted plugin catalog. When a string includes values supplied by users, the correct escaping and sanitization responsibilities remain in the host application. The target-language file is not a security boundary. Review whether text is going into an HTML element, an attribute, JavaScript or a URL, and use the appropriate rendering method.

A practical test is to translate a phrase containing an ampersand and render it alongside a dynamic name containing angle brackets. The app should show the intended words, not a broken attribute or unintended markup. Localization QA and output encoding reinforce each other; neither can replace the other.

Use context to resolve ambiguous words

The same English word can require different target-language translations depending on the screen. Order may be a customer’s purchase, an instruction to arrange records or the order of items in a list. Default can be a noun, adjective or button choice. WordPress provides context-aware gettext helpers such as _x() and its plural-context variants so distinct uses can be translated appropriately.

A context string describes meaning for the translator and participates in distinguishing the lookup. It is not simply a comment that can be translated, dropped or edited without consequences. Keep the context aligned with the call and extracted message. A PO entry with the right English source but wrong context may fail to match the runtime request.

When designing contexts, write practical distinctions such as noun: purchase or verb: arrange items. A generic label menu does not solve a meaning ambiguity. Add screenshots where one word remains unclear. The goal is a short, clear target that the user understands immediately rather than one mechanically reused across incompatible actions.

Translator comments prevent repeated guesswork

A developer comment can explain the meaning of a variable, a length constraint or an irreversible consequence. Place comments in the form expected by the extraction tooling so they appear beside the corresponding message. A translator deciding how to express Restore needs to know whether that means restoring a deleted post, resetting a setting or recovering a prior revision.

Comments should say what the user is doing. For example, a useful note might explain that a confirmation appears after a teacher permanently removes a student record, while a generic note saying translation of delete text adds little. Product context is especially important for consent, privacy, payment, account changes and accessibility.

Maintain comments as the feature evolves. A comment describing a reversible action becomes dangerous if engineering later makes that action permanent. Include changed context and source comments in the translation update report, even if the message’s visible English words did not change. Reviewers need the new product meaning, not just a familiar string.

Use formatting placeholders for dynamic values

PHP translation calls often work with sprintf or printf-style formatting. A sentence might say You have %d lessons remaining or The file %s was uploaded. The numeric value or filename belongs to runtime data and should not be translated as a literal example inside the PO target. Translators can move placeholders to achieve natural grammar, but they must preserve the intended argument identity.

Positional placeholders such as %1$s and %2$d are valuable when the target language needs to reorder arguments. The developer should use appropriate indexing, and the translator should know what each argument means. A raw count of percent signs does not validate a formatted message. A target may keep two specifiers but accidentally exchange the user’s name and the number of hours.

Run the exact formatter with unmistakably different values. Use a long non-Latin filename and a numeric count rather than two short words. Inspect the final displayed sentence and verify the data types. A valid PO file containing a malformed format specifier can still cause a runtime warning or misleading output when application code formats the string.

Format strings safely in the right order

Translation and escaping can interact with dynamic content. A developer should know whether escaping occurs before or after inserting values and how each input is trusted. A plain text message containing a filename has different needs from a link label inserted into an HTML attribute. Do not simply pass everything through one helper and hope the final output is safe.

A reliable pattern separates the translated format string from appropriately handled runtime data, and uses the correct formatting and escaping at the point of output. The exact PHP functions depend on the destination. Security review should consider whether translation files can be supplied by untrusted sources and whether the application later treats the result as markup.

Test uncommon input. A person name with quotation marks, an emoji, a very long title and a file path containing percent characters expose assumptions hidden by simple English examples. Technical QA verifies that data survives formatting. A language reviewer verifies that the resulting target sentence remains clear and polite.

WordPress plural functions require real quantities

WordPress provides plural-aware helpers such as _n() and context-aware _nx(). These functions are meant to choose the appropriate translation form based on a supplied count according to the loaded locale. The target language may require more plural forms than English, which commonly distinguishes singular and plural. Translators should supply the forms defined by the target catalog and its plural rules.

A count of zero is not automatically an error and does not necessarily have one universal grammatical expression. A message about no unpublished posts may sensibly invite the user to create the first post. A message about zero remaining attempts may be urgent. The language needs to reflect the business situation as well as the grammatical count.

Test several values through the actual runtime: zero, one, two, five, eleven and values relevant to the target grammar. Verify the displayed count if the design includes one. The plural selector and the numeric formatting argument are separate concerns; selecting the right branch does not guarantee that the number appears in the sentence automatically.

Distinguish singular and plural PO entries

A gettext catalog can store a source singular, a source plural and several target plural forms. A translator cannot safely replace the plural system with a pair of ordinary sentences without preserving that entry’s structure. The relevant catalog headers and tooling determine how many plural forms the locale expects.

Use a PO editor that understands plural records and warns about missing forms. Avoid machine-translation exports that flatten all plural variants into one target cell. A technically parsable file can still contain empty or duplicated forms that produce bad grammar for certain quantities.

For high-impact messages, inspect a full rendered example rather than only the target strings. A sentence about deleting several records must preserve both the correct object and the consequence. A target reviewer who sees only the generic plural label may miss that the action is irreversible.

POT is the source template, not a published translation

A POT file is a template of source messages and metadata. It lets translators create or update locale-specific PO files, but it is not normally the final target-language artifact the site loads for every user. Treat it as a versioned snapshot of the plugin’s translatable content.

Use the documented WP-CLI extraction command, such as wp i18n make-pot with the plugin source directory and a destination path. The extractor can scan relevant PHP and JavaScript sources and other supported plugin metadata. Choose a configuration that corresponds to what the product actually ships, including its source and build process.

After source changes, regenerate or reconcile the template rather than assuming last month’s POT still contains every message. Compare new, removed and changed entries. A translator should not have to guess whether an English source phrase changed its meaning or whether a key vanished because a component moved to another file.

PO files are editable translation records

A PO file commonly records msgid and msgstr fields, optional context, plurals and metadata. Translation tools use these records to connect source and target language. A source string can appear in different contexts with different targets, and a single plural record can contain multiple target forms. These details matter for both accuracy and lookup.

Keep the target-language file associated with a known source revision and locale. When a plugin update changes a message, reconcile the PO catalog and review fuzzy or changed entries before release. A PO editor may flag a previous translation as fuzzy because it resembles new source content. That is a suggestion to inspect, not proof that the old target is still appropriate.

Do not replace all identical English strings with one universal translation without context. Different screens can legitimately need different grammar and tone. PO context, developer comments and screenshots provide the evidence to make those choices.

MO output needs to match the deployed PHP messages

WordPress commonly uses compiled MO data for PHP-side gettext translations. WP-CLI documents wp i18n make-mo for producing MO files from PO sources. A correct PO file that has not been compiled or deployed through the site’s intended language-loading system may have no effect on what the user sees.

Build the target artifacts in a clean environment, place them under the expected naming and packaging convention, and test the site language. If PHP strings still display English, inspect the active text domain, locale and actual file lookup. An old MO or language pack may be taking precedence over the recently edited PO.

Make compilation part of a repeatable release script rather than a manual action someone remembers after a failed launch. Record output paths and checksums so the team knows which target files went live. The authoritative test is the running WordPress installation, not the presence of a freshly saved file on a developer’s laptop.

JavaScript strings use a separate loading route

The block editor and many modern WordPress interfaces run substantial client-side JavaScript. WordPress provides @wordpress/i18n, with functions such as __, _x and _n mirroring core translation concepts. A JavaScript string needs the correct domain and an appropriate translation-loading path; translating only PHP gettext output does not necessarily translate the editor UI.

Ensure the script declares or is registered with the dependencies required by its build process, including the WordPress i18n functionality when applicable. Mark human-facing JavaScript strings for extraction. Then associate the registered script handle and text domain with the translation data through the supported WordPress function.

A classic symptom is a settings page translated in PHP while the Gutenberg sidebar or custom block remains English. That does not mean the language provider ignored the sidebar. It may mean the JavaScript JSON was not generated, not matched to the correct script, or not loaded before the code requested its translations.

Why WordPress JavaScript needs JSON files

WordPress’s JavaScript localization infrastructure expects translation information in a suitable Jed-formatted JSON representation for scripts. WP-CLI documents wp i18n make-json to derive the needed per-script JSON assets from PO catalogs. The tool can write multiple JSON outputs, with naming tied to the relevant JavaScript source and domain.

Do not treat a generic JSON file containing a few English-to-French pairs as interchangeable with the expected WordPress script-translation artifact. The runtime must be able to associate messages, domain and plural metadata with the code that requests them. A JSON file can be valid JSON and still fail as a WordPress translation file.

Include one JavaScript-only string in the release fixture. If the PHP messages work but the JavaScript fixture does not, inspect the generated JSON’s association with its script, not the French sentence. This separates a delivery problem from a translation problem immediately.

Match the script handle, source path and translation file

WordPress’s wp_set_script_translations function associates a registered script handle with a text domain and optionally a translation path. The matching JSON filename may be based on a script handle or on a hash derived from the relevant source path, depending on the supported convention and generation workflow. That is why an apparently correct JSON file can be ignored after a build.

Modern JavaScript bundlers can rename, move or combine source files. If the translation JSON was produced against one path while WordPress registers another built asset, the lookup may no longer match. WP-CLI’s make-json workflow includes options intended to help with mapping source and build paths. The exact configuration should follow the app’s build setup.

Record the enqueue handle, built script path, text domain and generated JSON output for each major editor script. Test the compiled assets the plugin actually distributes, not only the unbundled development source. A translation that works in dev but disappears from the production build indicates a packaging or mapping issue.

Gutenberg block titles and settings need localization

A Gutenberg block can expose its title, description, category labels, inspector controls, toolbar buttons, placeholders and error messages. These are meaningful user-facing strings, even when the saved block output is language-neutral. A plugin may have excellent translated front-end prose while its editorial interface remains difficult for non-English-speaking authors.

Check each block’s metadata and registration path, as well as the JavaScript or PHP that supplies the controls. Some strings are declared through block metadata, others through JS helpers, and some are generated on the server. Extraction and language loading should cover the actual source of each message.

Test by opening the block inserter, inserting the block, changing its settings, creating a validation error and previewing or saving it. Confirm that labels match actions and do not mislead editors about what the block will publish. Translation QA for a content-management tool must include the author’s workflow, not just the reader’s public page.

Build scripts can silently detach translations

A source file might be called editor.js during development while the shipped bundle lives under build/index.js. The plugin’s registration code may point to the bundled file and its associated asset manifest. If JSON translation mapping still targets the development file, the compiled editor can fail to load the target language.

Always test the same build artifacts that will be packaged for release. If using an asset manifest, inspect which script handle and dependencies are registered. Run extraction and JSON generation according to the source-to-build mapping expected by the project. Do not hand-edit generated hash filenames without understanding what they identify.

Keep a build fixture that changes one known JS string, regenerates translations and verifies the localized output after compilation. Repeat after bundler upgrades or moving source directories. This catches a class of breakage that human translators have no way to diagnose by inspecting their PO entries.

WordPress.org language packs and bundled translations can interact

Plugins distributed through WordPress.org can receive translations from the community’s translation platform. The site’s installed language packs may supply strings according to WordPress’s loading logic. A plugin author may also bundle language files. The actual language shown can therefore depend on the environment and distribution method rather than on one file alone.

When testing a bundled fix, document which site language packs are installed, which plugin version is active and which catalog was loaded. If the target changed in the repository but not in a test installation, clear up the question of active translation provenance before editing more language. A cached or separately distributed language pack may explain the apparent mismatch.

Avoid trying to override the language system through undocumented hacks. WordPress’s translation APIs and documented loading filters provide supported routes for specific cases. Choose an approach appropriate to WordPress version and plugin distribution policy, and test it under upgrade conditions.

Site language and administrator language may differ

WordPress installations can have site-level language settings and per-user language preferences for administrative screens in supported configurations. A tester who switches the site language and then opens an editor under a different user preference may see mixed-language behavior that is expected from the configuration, not necessarily a broken catalog.

Write down the testing identity and effective locale. Use separate checks for the public site and the administrator’s editor when appropriate. If a target language appears in the front end but not in a user’s dashboard, confirm whether that user’s interface preference and the relevant JavaScript translations are aligned.

Test a clean account or controlled staging user before drawing conclusions. Language and user settings can interact with plugin metadata, installed packs and browser behavior. Reproducible QA requires knowing the environment rather than relying on a screenshot with no context.

Translate accessible labels and notices, not only visible buttons

A block editor contains controls that may be represented by icons, tooltips and accessible labels. If a translation misses the aria-label or screen-reader description of a button, the visible interface may look fine while some authors cannot identify the action. These strings should be in the extraction inventory alongside ordinary captions.

Write accessible language for the actual control. An icon might mean Move block up, Open block settings or Remove image. A generic label like Icon is not useful. Some screen readers already announce the role of a button, so repeating button unnecessarily may make the output cumbersome. Target-language review should listen to the interface, not just read it.

Inspect dynamic states. A publishing button may change from Publish to Publishing, and a network failure might announce that saving did not complete. Correct language matters because an author must know whether content is live. Make those states part of the test plan.

Preserve placeholders in notices and administrative messages

WordPress plugins often include notices such as Import completed: %d records processed. Translators may reorder the number or choose a different grammatical form, but must not remove required argument identities. A message with both a file name and an error reason needs clear context so the target does not reverse what failed.

Use positional placeholders when the order may legitimately change between languages. Give translators sample values that reveal the role of each argument. Check whether the caller inserts escaped data or formats the message for HTML. A percent-sign replacement error can range from an ugly label to an inaccurate count, so technical validation must cover real output.

Test across zero, one and larger counts where grammar changes. If the notice requires a plural branch, use the plural-aware mechanism rather than relying on an English suffix appended after a numeric value. That makes the whole message editable and avoids building sentences from fragments.

Security and trust in translation supply chains

A translation catalog is data, but it enters a system that renders HTML, attributes, JavaScript messages and administrative controls. Protect the import route from arbitrary code modifications. PO strings should not be used as a pathway to edit plugin PHP, enqueue unfamiliar scripts or change security settings. Treat externally supplied catalogs as inputs requiring validation and review.

Check formatting and markup contracts. A translator should not be asked to insert raw JavaScript or unapproved HTML to make a message fit. If a dynamic value includes user content, let the application’s escaping logic handle it. A plugin translation cannot substitute for safe coding practices in its UI.

Review the package diff before deployment. The approved file changes should be limited to expected translation resources and generated assets. Unexpected source-code modifications or changes in text domain should be routed to engineering and security review rather than silently accepted as part of a routine language update.

Right-to-left languages need editor interaction tests

Arabic and Hebrew WordPress interfaces mix RTL prose with Latin slugs, URLs, email addresses, percentages and technical identifiers. This can affect punctuation, selection and control alignment. A correctly translated paragraph can still become hard to read if the plugin’s custom editor sidebar assumes left-to-right layout everywhere.

Test plugin controls under an RTL site or user language. Verify that directional layout, icons and dynamic data behave appropriately. Long URLs and verification codes should remain in a usable logical order. Avoid inserting invisible directional marks into every translated sentence without first checking the underlying component’s rendering.

Use real screen-reader and keyboard navigation tests for important editing tasks. A public-facing multilingual plugin should be usable by authors as well as visitors. When a layout defect belongs to CSS or component code, fix the application rather than forcing translators to distort their language to accommodate it.

Translation consistency should follow meaning and context

A plugin may use Publish, Save, Update, Apply and Confirm for different actions. A global translation-memory match may reuse one target verb across all five, even though the consequences differ. Some words describe a draft change; others make content visible to everyone. The language reviewer needs the product distinction.

Attach context: where the message appears, what it changes, whether the operation is reversible and who will see the result. Maintain a concept-oriented glossary rather than a list of English words with one mandatory equivalent. In a long-lived plugin, consistent terminology reduces user confusion, but mechanical uniformity can introduce errors.

When a source changes, review the affected string even if a previous translation memory match is exact. A message once describing a reversible unpublish operation may now describe permanent deletion. Translation memory is useful as a starting point, not as evidence that the target still conveys the correct intent.

A source-to-release translation checklist

First confirm the plugin’s domain and extraction coverage. Generate the POT against the intended source version. Translate each target PO, including plurals and contexts, then compile or generate the runtime assets used by the product. For JavaScript, create the matching JSON resources and verify script handles and paths. Review language-pack behavior where relevant.

Second test the user interface. Change locale in a controlled installation, inspect PHP-rendered settings pages and JavaScript editor screens, exercise a variable-containing notice and several plural counts, and verify tooltips and accessible labels. Test the release bundle, not just local source files. Capture the plugin version, WordPress version, locale and observed output in the test record.

Third obtain target-language sign-off. Does the wording make the intended action clear? Are permission and deletion warnings accurate? Do translated links and buttons help readers complete the task? A localized plugin is ready when language and behavior agree, not when every row in a spreadsheet is filled.

A worked failure: PHP translates but the block editor does not

A developer creates a correct French PO and MO, switches the WordPress site to French and confirms that server-rendered settings show French. Yet the custom Gutenberg block’s sidebar remains English. The first suspicion might be a bad translation, but the source may contain valid French strings for that sidebar.

Inspect the JavaScript source for @wordpress/i18n calls and the correct text domain. Confirm the script’s registered handle, whether wp_set_script_translations is associated with it, and whether the corresponding JSON translation assets were generated and deployed. Check the production bundle path if it differs from the development source path.

When the correct JSON is loaded, test a distinctive sidebar label. Add an integration smoke test that requires both a PHP-facing and a JS-facing phrase in the target locale. This prevents a future release from repeating the same split-language experience.

A worked failure: the translator changes the placeholder number

An export shows a plugin notice saying Uploaded %1$s and skipped %2$d items. The target language needs the skipped count first, so the translator rearranges the placeholders. That can be correct, but if the file-name placeholder and numeric placeholder identities are exchanged, the result may show a number in the place of a filename or fail formatting.

Give each parameter a description. Test with a file named course-list.csv and a count of seven. Verify that the target sentence gives the correct relationship between uploaded and skipped items. Preserve the format conversion and argument identity even if the target sentence starts with the second value.

When the issue is fixed, update the translator note and placeholder linting rule. The best repair prevents the same ambiguity in future target languages, rather than merely correcting one French message.

A worked failure: a language file is ignored after bundling

A block’s source JavaScript is extracted to a JSON translation asset, and everything works during development. A release build moves the script into a different build directory. WordPress registers the bundled path, while the JSON filename or mapping still reflects the old location. The localized block silently shows source-language text.

Reproduce the issue using the packaged plugin. Record the actual registered script handle and URL. Compare the translation JSON generated from the source with the script path the WordPress runtime uses. Apply the supported filename or mapping workflow and regenerate the assets.

Test again after a clean deployment. A source-file smoke test alone is not enough because the failure exists at the build and runtime boundary. Automating this check pays off every time the bundler, directory structure or entrypoint names change.

A worked failure: an action label changes meaning

A plugin originally uses the label Remove draft for a reversible operation. A product update changes the action into Delete permanently but keeps an old target-language word equivalent to Hide. All translation files load, and every placeholder check passes. The failure is semantic: the user has been told the wrong consequence.

Treat source changes that affect consequences as high-risk review triggers. Compare the previous and current behavior, not only the English text. Ask a qualified reviewer to write target wording that communicates permanence and the affected content. Review it alongside the confirmation dialog and the button that executes the action.

This is why technical QA is necessary but not sufficient. Code and catalog validation can prove that the right string reaches the right place; only contextual review can establish that the sentence tells the truth about the action.

How to audit a large plugin translation library

Start by inventorying text domains, runtime languages, PHP message sets and JavaScript-generated catalogs. Cross-check POT entries against current source and identify missing or stale targets. Separate framework, plugin and theme ownership so that one team does not accidentally change another component’s translation keys.

Next categorize defects: extraction omissions, incorrect context, placeholder mismatches, plural forms, compiled assets, script JSON paths, locale routing and linguistic meaning. Prioritize critical user tasks such as account access, commerce, consent, publishing and destructive actions. Track whether issues repeat after updates, because a recurring defect often indicates a broken pipeline rather than careless translators.

Keep a single issue record per source problem and link affected locales. A misplaced script handle can cause the same untranslated sidebar in ten languages. Fixing the handle once is more efficient than editing ten catalogs separately. Likewise, a misleading English source message should be clarified before being propagated to new target languages.

Frequently asked questions about WordPress translation

What is the difference between POT, PO and MO? POT is a source template, PO stores editable translation records, and MO is a commonly used compiled gettext translation format. WordPress JavaScript has its own JSON translation requirements.

Why is my WordPress plugin still in English after I translated its PO file? The active site may be using another locale, text domain, compiled file or language pack. PHP-side translations also need the correct deployment path. JavaScript requires separate script translation loading. Test the actual runtime rather than assuming a PO save changed the live site.

What does wp i18n make-pot do? It extracts translatable messages from the supported WordPress project sources into a POT template. Use it on the source and configuration appropriate to the plugin release.

What does wp i18n make-json do? It generates the WordPress JavaScript translation JSON assets from PO input, with per-script naming and mapping rules. It is not the same as producing one arbitrary JSON dictionary for all scripts.

Should I translate the text domain? No. The text domain identifies the plugin or theme and must match the code and resource-loading contract. Translate the user-facing message, not its domain or key identity.

How are Gutenberg block translations loaded? JavaScript strings should use the supported WordPress i18n functions, and the registered script must be associated with the appropriate translations, including the matching JSON asset where needed.

Can I use one English phrase translation everywhere? Only when the meaning and grammatical context are actually the same. Use translation context for ambiguous words and review the reader’s task.

Official WordPress references and practical next steps

The WordPress Developer Handbook explains PHP plugin internationalization and text domains at https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/ . The Block Editor Handbook explains JavaScript translation and wp_set_script_translations at https://developer.wordpress.org/block-editor/how-to-guides/internationalization/ . WP-CLI documents extraction and conversion at https://developer.wordpress.org/cli/commands/i18n/make-pot/ , https://developer.wordpress.org/cli/commands/i18n/make-mo/ and https://developer.wordpress.org/cli/commands/i18n/make-json/ .

For the connected translation system, use https://edukatesg.com/how-people-translate-quickly-series-index/ , https://edukatesg.com/2026/10/19/how-people-translate-quickly-gettext-po-pot-translation-qa/ and https://edukatesg.com/2026/09/19/how-people-translate-quickly-localization-build-validation/ . The larger system is explained at https://edukatesg.com/2026/09/18/master-art-of-translation-complete-system-moving-meaning-between-languages/ .

Start by translating one simple PHP label, one PHP plural, one formatted notice, one block-editor label and one accessibility description. Extract, translate, generate compiled assets, install a clean plugin build and verify every message under the same target-language WordPress environment. Once all five work, the rest of the plugin can move through a proven pipeline that protects both the reader’s meaning and the software’s behavior.

Discover more from eduKate Singapore

Subscribe now to keep reading and get access to the full archive.

Continue reading