Skip to content

I18N: Add translation support for script modules#11543

Open
manzoorwanijk wants to merge 2 commits intoWordPress:trunkfrom
manzoorwanijk:add/script-module-translations
Open

I18N: Add translation support for script modules#11543
manzoorwanijk wants to merge 2 commits intoWordPress:trunkfrom
manzoorwanijk:add/script-module-translations

Conversation

@manzoorwanijk
Copy link
Copy Markdown
Member

@manzoorwanijk manzoorwanijk commented Apr 10, 2026

Summary

Adds translation support for script modules (WP_Script_Modules), mirroring the existing wp_set_script_translations() infrastructure for classic scripts.

Script modules (ES modules registered via wp_register_script_module()) currently have no way to load i18n translation data. This means any strings using __() from @wordpress/i18n inside script modules remain untranslated. This affects the new admin pages in WordPress 7.0+ that are built as script modules, including Connectors and Fonts.

Trac ticket: https://core.trac.wordpress.org/ticket/65015

Changes

New public API

  • wp_set_script_module_translations( $id, $domain, $path ) — registers a text domain for a script module (in script-modules.php)
  • load_script_module_textdomain( $id, $domain, $path ) — loads translation JSON files for a script module, resolving the file path from the module's source URL (in l10n.php)

WP_Script_Modules class changes

  • Added set_translations() method — stores text domain and translation path per module
  • Added get_registered_src() method — public accessor for a module's raw source URL (used by load_script_module_textdomain())
  • Added print_script_module_translations() method — outputs inline <script> tags calling wp.i18n.setLocaleData() for each enqueued module with translations
  • Hooked print_script_module_translations() at priority 11 on admin_print_footer_scripts (after classic scripts load wp-i18n at priority 10) and priority 21 on wp_footer (after wp_print_footer_scripts at priority 20)

Automatic translation setup

  • wp_default_script_modules() now calls wp_set_script_module_translations() for all @wordpress/* script modules that list wp-i18n in their dependencies

Tests

  • 7 new unit tests covering set_translations(), get_registered_src(), wp_set_script_module_translations(), and print_script_module_translations()

How it works

The flow mirrors classic script translations:

  1. wp_set_script_module_translations() is called after registering a script module, storing the text domain and optional path
  2. When the page renders, print_script_module_translations() iterates over all enqueued modules (and their dependencies) that have translations set
  3. For each, it calls load_script_module_textdomain() which resolves the module's source URL to a relative path, computes an MD5 hash, and looks for the corresponding JSON translation file (same naming convention as classic scripts)
  4. If found, it outputs an inline <script> calling wp.i18n.setLocaleData() with the translated strings
  5. These inline scripts execute before the deferred ES modules, ensuring translations are available when modules run

Related

Test plan

Automated tests

Run the script module tests, which now include end-to-end coverage for translation printing:

npm run test:php -- --group script-modules

The new tests test_print_script_module_translations_outputs_set_locale_data and test_print_script_module_translations_includes_dependencies use the pre_load_script_translations filter to provide mock translations (no fixture files needed) and assert that the rendered inline script contains the expected wp.i18n.setLocaleData() call with the translated data.

Manual verification (optional)

Language packs don't include JSON translation files for the new script modules yet, so manual end-to-end verification requires a small mu-plugin to provide mock translations. Paired with the companion Gutenberg PR (#77214), no wp_set_script_module_translations() registration is needed — the build templates call it automatically.

1. Set up the test environment:

  • Switch the site language to any non-English language in Settings > General
  • Drop the following mu-plugin into src/wp-content/mu-plugins/test-script-module-translations.php (create the mu-plugins directory if it doesn't exist):
test-script-module-translations.php
<?php
/**
 * Test mu-plugin: Provides mock translations for the connectors content module.
 * DELETE after testing.
 *
 * Registers translations for the connectors route module (since `routes.php` in
 * `src/wp-includes/build/` is auto-generated and doesn't yet call
 * `wp_set_script_module_translations()` — that change lives in Gutenberg PR #77214),
 * and provides mock Spanish translations via the `pre_load_script_translations`
 * filter so no language pack JSON files are needed.
 */

add_action( 'admin_enqueue_scripts', function () {
	add_action( 'options-connectors-wp-admin_init', function () {
		wp_set_script_module_translations( 'wp/routes/connectors-home/content', 'default' );
	}, 20 );
}, 5 );

add_filter( 'pre_load_script_translations', function ( $translations, $file, $handle ) {
	if ( 'wp/routes/connectors-home/content' !== $handle ) {
		return $translations;
	}
	return wp_json_encode( array(
		'locale_data' => array(
			'messages' => array(
				''           => array( 'domain' => 'messages', 'lang' => 'es' ),
				'Set up'     => array( 'Configurar' ),
				'Install'    => array( 'Instalar' ),
				'Connectors' => array( 'Conectores' ),
			),
		),
	) );
}, 10, 3 );

2. Verify:

  • Navigate to Settings > Connectors (/wp-admin/options-connectors.php)
  • Expected: The heading shows "Conectores" and buttons show "Instalar" / "Configurar"
  • View page source and search for js-module-translations — inline <script> tags with IDs like wp/routes/connectors-home/content-js-module-translations should appear after the classic scripts

3. Clean up:

  • Delete src/wp-content/mu-plugins/test-script-module-translations.php

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 4.6
Used for: Implementation, tests, and PR description were authored with AI assistance; reviewed and tested by me.

Add `wp_set_script_module_translations()` and supporting infrastructure
to enable i18n for script modules (ES modules), mirroring the existing
`wp_set_script_translations()` for classic scripts.

Script modules registered via `wp_register_script_module()` currently
have no way to load translation data, leaving strings untranslated on
pages like Connectors and Fonts that are built as script modules.

New public API:
- `wp_set_script_module_translations()` in script-modules.php
- `load_script_module_textdomain()` in l10n.php

New methods on `WP_Script_Modules`:
- `set_translations()` — stores text domain per module
- `get_registered_src()` — public accessor for module source URL
- `print_script_module_translations()` — outputs inline setLocaleData()
  calls after classic scripts load but before modules execute

See #65015.
@github-actions
Copy link
Copy Markdown

Hi @manzoorwanijk! 👋

Thank you for your contribution to WordPress! 💖

It looks like this is your first pull request to wordpress-develop. Here are a few things to be aware of that may help you out!

No one monitors this repository for new pull requests. Pull requests must be attached to a Trac ticket to be considered for inclusion in WordPress Core. To attach a pull request to a Trac ticket, please include the ticket's full URL in your pull request description.

Pull requests are never merged on GitHub. The WordPress codebase continues to be managed through the SVN repository that this GitHub repository mirrors. Please feel free to open pull requests to work on any contribution you are making.

More information about how GitHub pull requests can be used to contribute to WordPress can be found in the Core Handbook.

Please include automated tests. Including tests in your pull request is one way to help your patch be considered faster. To learn about WordPress' test suites, visit the Automated Testing page in the handbook.

If you have not had a chance, please review the Contribute with Code page in the WordPress Core Handbook.

The Developer Hub also documents the various coding standards that are followed:

Thank you,
The WordPress Project

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 10, 2026

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props manzoorwanijk, mukesh27.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions
Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@mukeshpanchal27
Copy link
Copy Markdown
Member

Thanks for the PR! Can you expose which AI tool do you use in PR?

## Use of AI Tools

<!--
You are free to use artificial intelligence (AI) tooling to contribute, but you must disclose what tooling you are using and to what extent a pull request has been authored by AI. It is your responsibility to review and take responsibility for what AI generates. See the WordPress AI Guidelines: <https://make.wordpress.org/ai/handbook/ai-guidelines/>.

Example disclosure:

AI assistance: Yes
Tool(s): GitHub Copilot, ChatGPT
Model(s): GPT-5.1
Used for: Initial code skeleton and test suggestions; final implementation and tests were reviewed and edited by me.
-->

@manzoorwanijk
Copy link
Copy Markdown
Member Author

Thanks for the PR! Can you expose which AI tool do you use in PR?

Updated. Thanks

manzoorwanijk added a commit to WordPress/gutenberg that referenced this pull request Apr 10, 2026
Add two integration tests verifying the full translation flow:

- test_print_script_module_translations_outputs_set_locale_data covers
  the happy path, asserting that the inline script contains the
  expected module ID, the wp.i18n.setLocaleData() call, and the
  translated string.
- test_print_script_module_translations_includes_dependencies covers
  translations for dependency modules (not just directly enqueued ones).

Both tests use the pre_load_script_translations filter to provide
mock translation data inline, so no fixture JSON files are needed.

See #65015.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants