Skip to content

I18N: Add translation support for script modules#77214

Open
manzoorwanijk wants to merge 3 commits intotrunkfrom
add/script-module-translations
Open

I18N: Add translation support for script modules#77214
manzoorwanijk wants to merge 3 commits intotrunkfrom
add/script-module-translations

Conversation

@manzoorwanijk
Copy link
Copy Markdown
Member

@manzoorwanijk manzoorwanijk commented Apr 10, 2026

What?

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

Related PR: WordPress/wordpress-develop#11543

Adds translation support for script modules so that strings using __() from @wordpress/i18n inside script modules are properly translated.

Why?

Script modules (ES modules registered via wp_register_script_module()) have no mechanism to load i18n translation data. Classic scripts use wp_set_script_translations() to load JSON translation files and call wp.i18n.setLocaleData(), but no equivalent exists for script modules.

This means strings in any script module remain in English regardless of the site language. In WordPress 7.0+, this affects the new admin pages built as script modules — Connectors and Fonts — where strings like "Set up", "If the connector you need is not listed", and "All of your API keys and credentials are stored here" are never translated.

The Core side of this fix adds wp_set_script_module_translations() and the underlying infrastructure to WP_Script_Modules. This PR provides:

  1. A polyfill so the Gutenberg plugin works on WP versions before the Core change lands
  2. Updates to the build templates so generated code calls wp_set_script_module_translations() for modules and routes that use wp-i18n

How?

Polyfill (lib/compat/wordpress-7.0/script-modules.php)

  • wp_set_script_module_translations() — stores text domain and path per module ID in a global array
  • load_script_module_textdomain() — resolves the module's source URL to a relative path, computes an MD5 hash, and loads the JSON translation file (same logic as load_script_textdomain())
  • gutenberg_print_script_module_translations() — hooked to admin_print_footer_scripts (priority 11) and wp_footer (priority 21), outputs inline <script> tags calling wp.i18n.setLocaleData() after classic scripts like wp-i18n are loaded but before deferred ES modules execute
  • gutenberg_get_script_module_src() — helper to get a module's raw source URL, using WP_Script_Modules::get_registered_src() when available or falling back to reflection for older WP versions

All functions are guarded with function_exists() checks so they yield to Core's implementation when available.

Build template updates

  • routes-registration.php.template — after registering each route content/route script module, calls wp_set_script_module_translations() if the module's asset file lists wp-i18n in its dependencies
  • module-registration.php.template — same pattern for @wordpress/* script module packages

All template calls are guarded with function_exists( 'wp_set_script_module_translations' ) for safety.

Testing Instructions

Language packs don't include JSON translation files for script modules yet, so testing requires a small mu-plugin to provide test translations.

1. Set up the test environment:

  • Rebuild Gutenberg: npm run build
  • Save the mu-plugin below as test-script-module-translations.php in the repo root
  • Create or update .wp-env.override.json in the repo root to map the mu-plugin:
{
	"mappings": {
		"wp-content/mu-plugins/test-script-module-translations.php": "./test-script-module-translations.php"
	}
}
  • Restart the environment: npm run wp-env stop && npm run wp-env start
  • Switch the site language to any non-English language (e.g., Spanish) in Settings > General
test-script-module-translations.php
<?php
/**
 * Test mu-plugin: Provides mock translations for script module strings.
 * Drop this file into wp-content/mu-plugins/ to test script module translations.
 * DELETE after testing.
 *
 * Provides mock Spanish translations via the pre_load_script_translations filter
 * so no language pack JSON files are needed.
 */

// Provide mock translations via filter.
add_filter( 'pre_load_script_translations', function ( $translations, $file, $handle, $domain ) {
	if ( 'wp/routes/connectors-home/content' !== $handle ) {
		return $translations;
	}

	return wp_json_encode( array(
		'domain'      => 'messages',
		'locale_data' => array(
			'messages' => array(
				''           => array( 'domain' => 'messages', 'lang' => 'test' ),
				'Set up'     => array( 'Configurar' ),
				'Install'    => array( 'Instalar' ),
				'Cancel'     => array( 'Cancelar' ),
				'Connectors' => array( 'Conectores' ),
				'All of your API keys and credentials are stored here and shared across plugins. Configure once and use everywhere.' =>
					array( 'Todas tus claves API y credenciales se almacenan aqui.' ),
				'If the connector you need is not listed, <a>search the plugin directory</a> to see if a connector is available.' =>
					array( 'Si el conector que necesitas no aparece, <a>busca en el directorio de plugins</a>.' ),
			),
		),
	) );
}, 10, 4 );

2. Verify the Connectors page:

  • Navigate to Settings > Connectors (/wp-admin/options-connectors.php)
  • Expected: The heading shows "Conectores", the subtitle and footer text are in Spanish, and buttons show "Instalar" / "Configurar" / "Cancelar"
  • Before this patch: All these strings remain in English regardless of site language

3. Verify infrastructure in page source:

  • View the page source and search for js-module-translations
  • Expected: Inline <script> tags with IDs like wp/routes/connectors-home/content-js-module-translations appear after the classic scripts and before the <script type="module"> tag
  • These scripts contain wp.i18n.setLocaleData() calls with the translation data

4. Clean up:

  • Delete test-script-module-translations.php and .wp-env.override.json (or remove the mapping), then restart the environment

Testing Instructions for Keyboard

No UI changes — this is infrastructure-only. Keyboard navigation is unaffected.

Screenshots or screencast

Before After
Connectors page with untranslated English strings despite Arabic site language Connectors page with strings translated to Arabic (heading, subtitle, buttons, footer text)

Use of AI Tools

This PR was authored with assistance from Claude Code (Claude Opus 4.6).

Add polyfill for `wp_set_script_module_translations()` and update build
templates to call it for script modules that depend on `wp-i18n`.

Script modules have no mechanism to load i18n translation data, leaving
strings in ES modules untranslated regardless of site language. This
affects admin pages built as script modules like Connectors and Fonts.

Changes:
- Add polyfill in lib/compat/wordpress-7.1/script-modules.php with
  wp_set_script_module_translations(), load_script_module_textdomain(),
  and gutenberg_print_script_module_translations()
- Update routes-registration.php.template to set translations for route
  content and route modules that use wp-i18n
- Update module-registration.php.template to set translations for
  @wordpress/* script module packages that use wp-i18n

All calls guarded with function_exists() for forward compatibility with
the Core implementation.

See https://core.trac.wordpress.org/ticket/65015.
@github-actions
Copy link
Copy Markdown

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.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: manzoorwanijk <manzoorwanijk@git.wordpress.org>

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

@manzoorwanijk manzoorwanijk self-assigned this Apr 10, 2026
@manzoorwanijk manzoorwanijk added the [Type] Bug An existing feature does not function as intended label Apr 10, 2026
@manzoorwanijk manzoorwanijk requested a review from desrosj April 10, 2026 01:45
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 10, 2026

Flaky tests detected in cf9468d.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/24244336065
📝 Reported issues:

Move the script modules translation polyfill from the wordpress-7.1
compat directory to wordpress-7.0 so the fix targets the 7.0 release,
which is where the new admin pages (Connectors, Fonts) using script
modules were introduced.

Also moves the backport changelog entry accordingly.

See https://core.trac.wordpress.org/ticket/65015.
@t-hamano t-hamano added [Type] Enhancement A suggestion for improvement. [Feature] Script Modules API Related to the Script Modules API that adds support for native ES modules and import maps and removed [Type] Bug An existing feature does not function as intended labels Apr 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Script Modules API Related to the Script Modules API that adds support for native ES modules and import maps [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants