Skip to content

Premium Analytics: say where each widget module's translations live - #52634

Merged
retrofox merged 3 commits into
trunkfrom
update/pa-extensibility-widget-i18n
Sep 23, 2026
Merged

retrofox merged 3 commits into
trunkfrom
update/pa-extensibility-widget-i18n

Conversation

@retrofox

@retrofox retrofox commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Fixes WOOA7S-2186

Proposed changes

Step 2 of 4 of the widget-type extensibility stack (umbrella: #52637). Step 1 (#52568) lets a plugin register widget types from its own build; this step lets the dashboard translate them.

What?

Every widget module record says where its bundles' translation catalogs live, and the client loads them from there.

  • Widget_Type gains textdomain, the domain the widget's metadata and bundles are stamped with, and i18n_manifest, the URL of the i18n-manifest.json of the build that serves its modules. /wpcom/v2/widget-modules publishes both.
  • register_widget_types_from_manifest( $widgets, $args ) takes both in $args as defaults for candidates that declare none. register_widget_type() accepts them like any other property.
  • The package registers its own widgets with its text domain and no manifest: the page's boot init module already loads the package's catalogs.
  • createWidgetModuleResolver( records ) builds the resolveWidgetModule the four dashboards hand to WidgetDashboard, through a useWidgetModuleResolver() hook. Before importing a module it caches its build's manifest, once per domain, and loads the bundle's catalog under the record's domain. The metadata (widget.js) preload does the same per record.
  • loadI18nManifest( domain, url ) in wp-build-polyfills caches another build's manifest, the counterpart of what loadI18nCatalogs() does for the page's own build at boot.
  • Module id to bundle path works for any handle prefix, {prefix}/widgets/{dir}/{render,widget} to build/widgets/{dir}/{render,widget}.js, not the package's alone.

Why?

A plugin's widget bundles are stamped with the plugin's text domain and listed in the plugin's manifest, which the dashboard page never loads: boot loads the package's own manifest and nothing else. Without a record saying where its catalogs live, a plugin's widgets render in English. The first consumer is the Ads package, #52635.

How?

A record without a text domain, from an older server, is treated as the package's own, so nothing changes for the package's widgets. A domain already cached keeps its bundle set, whatever URL a later call names, and a manifest is published before it resolves, so a catalog load right after it waits rather than skips. The catalog load hashes the bundle path relative to the plugin, the way WordPress names JS translation files, so a package vendored inside a plugin keeps aliasing its text domain in the plugin's i18n-map.php, as this package does.

Docs come with step 4 (#52636).

Also carries the review follow-ups from #52568: the widget-availability.php header now says the policy covers manifest candidates only, the registry test requires default-dashboard-sections.php itself, the version-shape test is gone, and the duplicate-name test asserts the type is still registered.

Related product discussion/links

Does this pull request change what data or activity we track or use?

No.

Testing instructions

cd projects/packages/premium-analytics && composer phpunit
cd projects/packages/premium-analytics && pnpm run test --testPathPatterns=widget-module-i18n
cd projects/packages/wp-build-polyfills && pnpm run test

A plugin's record

Add this mu-plugin. It registers the package's own Clicks bundles again under a demo/ module id, and a type on them under a demo text domain with the package's manifest, so it needs no build. Its own ids matter: the dashboard caches an imported render module by id, so a type that reuses jetpack-premium-analytics/widgets/clicks/render would reuse the import Clicks already made, catalog included.

add_action( 'init', function () {
	$dir = WP_PLUGIN_DIR . '/jetpack/jetpack_vendor/automattic/jetpack-premium-analytics/build/';
	$url = plugins_url( 'jetpack_vendor/automattic/jetpack-premium-analytics/build/', 'jetpack/jetpack.php' );
	$ext = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '.js' : '.min.js';
	foreach ( array( 'render', 'widget' ) as $kind ) {
		$asset = require $dir . "widgets/clicks/{$kind}.min.asset.php";
		wp_register_script_module(
			"demo/widgets/clicks/{$kind}",
			$url . "widgets/clicks/{$kind}" . $ext,
			$asset['module_dependencies'] ?? array(),
			$asset['version'] ?? false
		);
	}
} );

add_action( 'jetpack_premium_analytics_register_widget_types', function () {
	\Automattic\Jetpack\PremiumAnalytics\register_widget_type(
		'demo/clicks',
		array(
			'render_module' => 'demo/widgets/clicks/render',
			'widget_module' => 'demo/widgets/clicks/widget',
			'category'      => 'stats',
			'title'         => 'Demo clicks',
			'textdomain'    => 'demo',
			'i18n_manifest' => plugins_url( 'jetpack_vendor/automattic/jetpack-premium-analytics/build/i18n-manifest.json', 'jetpack/jetpack.php' ),
		)
	);
}, 20 );
  1. GET /wp-json/wpcom/v2/widget-modules shows textdomain: "demo" and the manifest URL on demo/clicks. The package's own records (jpa/*) show textdomain: "jetpack-premium-analytics-pkg" and i18n_manifest: null.
image
  1. Switch the site to another locale (wp language core install es_ES --activate;
    wp.jpI18nLoader.state.locale in the console must not read en_US).
image

Open the widget picker and add "Demo clicks" to a section.

The network tab shows, in this order:

  • one request for i18n-manifest.json
  • one for wp-content/languages/plugins/demo-es_ES-<md5>.json
  • then widgets/clicks/render.min.js.

No build ships a demo catalog, so the widget renders in English: a 404 is swallowed quietly, and a dev site that answers a missing file with a redirect to an HTML page logs a [jetpack-i18n] Failed to load "demo" catalog warning instead.

  1. Change textdomain to jetpack-premium-analytics-pkg and reload. No manifest request this time: the domain is the page's own, cached at boot, and the catalog is the one the package's Clicks uses.

Under en_US none of these requests happen, as before.

@retrofox retrofox added Enhancement Changes to an existing feature — removing, adding, or changing parts of it [Status] In Progress labels Sep 22, 2026
@retrofox retrofox self-assigned this Sep 22, 2026
@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.

  • To test on WoA, go to the Plugins menu on a WoA dev site. Click on the "Upload" button and follow the upgrade flow to be able to upload, install, and activate the Jetpack Beta plugin. Once the plugin is active, go to Jetpack > Jetpack Beta, select your plugin (Jetpack or WordPress.com Site Helper), and enable the update/pa-extensibility-widget-i18n branch.
  • To test on Simple, run the following command on your sandbox:
bin/jetpack-downloader test jetpack update/pa-extensibility-widget-i18n
bin/jetpack-downloader test jetpack-mu-wpcom-plugin update/pa-extensibility-widget-i18n

Interested in more tips and information?

  • In your local development environment, use the jetpack rsync command to sync your changes to a WoA dev blog.
  • Read more about our development workflow here: PCYsg-eg0-p2
  • Figure out when your changes will be shipped to customers here: PCYsg-eg5-p2

@github-actions

Copy link
Copy Markdown
Contributor

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • ✅ Add a "[Status]" label (In Progress, Needs Review, ...).
  • ✅ Add testing instructions.
  • ✅ Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖


Follow this PR Review Process:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Make sure to test your changes on all platforms that it applies to. You're responsible for the quality of the code you ship.
  3. You can use GitHub's Reviewers functionality to request a review.
  4. When it's reviewed and merged, you will be pinged in Slack to deploy the changes to WordPress.com simple once the build is done.

If you have questions about anything, reach out in #jetpack-developers for guidance!

@jp-launch-control

jp-launch-control Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Code Coverage Summary

Coverage changed in 10 files. Only the first 5 are listed here.

File Coverage Δ% Δ Uncovered
projects/packages/videopress/src/client/components/chapters-editor/preview/use-preview-playback.ts 126/148 (85.14%) -1.35% 2 ❤️‍🩹
projects/packages/wp-build-polyfills/src/js/load-i18n-catalogs.ts 578/597 (96.82%) 0.04% 2 ❤️‍🩹
projects/packages/premium-analytics/routes/author-detail/stage.tsx 29/29 (100.00%) 0.00% 0 💚
projects/packages/premium-analytics/routes/dashboard/stage.tsx 62/67 (92.54%) 0.11% 0 💚
projects/packages/premium-analytics/routes/post-detail/stage.tsx 24/24 (100.00%) 0.00% 0 💚

Full summary · PHP report · JS report

@retrofox
retrofox added this pull request to stack #52692 September 23, 2026 08:53
Base automatically changed from update/pa-extensibility-widget-types-action to trunk September 23, 2026 11:56
@retrofox
retrofox force-pushed the update/pa-extensibility-widget-i18n branch from e773f41 to 95fdf76 Compare September 23, 2026 11:56
@retrofox
retrofox marked this pull request as ready for review September 23, 2026 11:57
@retrofox
retrofox requested a review from a team as a code owner September 23, 2026 11:57
@retrofox retrofox added [Status] Needs Review This PR is ready for review. and removed [Status] In Progress labels Sep 23, 2026

@Nikschavan Nikschavan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, the changes look good. One small note on the testing steps: pnpm run test -- --testPathPatterns=widget-module-i18n exits with "No tests found" because pnpm passes the -- through to jest. pnpm run test --testPathPatterns=widget-module-i18n runs the 34 tests.

@retrofox
retrofox force-pushed the update/pa-extensibility-widget-i18n branch from 9b105a4 to 7ca9110 Compare September 23, 2026 14:36
@retrofox

Copy link
Copy Markdown
Contributor Author

Good catch, pnpm forwards the -- to jest. Fixed the command in the testing steps.

@retrofox
retrofox force-pushed the update/pa-extensibility-widget-i18n branch 2 times, most recently from 5f0dce9 to bf35ba1 Compare September 23, 2026 15:20
textdomain and i18n_manifest per type; the client loads a plugin's widget catalogs from them
require default sections in the registry test, drop the version-shape test, fix the availability header
@retrofox
retrofox force-pushed the update/pa-extensibility-widget-i18n branch from bf35ba1 to 3cc66f9 Compare September 23, 2026 15:57
@retrofox
retrofox merged commit a756062 into trunk Sep 23, 2026
112 of 113 checks passed
@retrofox
retrofox deleted the update/pa-extensibility-widget-i18n branch September 23, 2026 16:49
retrofox added a commit that referenced this pull request Sep 23, 2026
…52634)

* add the catalog location to widget module records
textdomain and i18n_manifest per type; the client loads a plugin's widget catalogs from them

* apply the review follow-ups from #52568

require default sections in the registry test, drop the version-shape test, fix the availability header

* mock the widget module resolver in the stage test
@github-actions github-actions Bot removed the [Status] Needs Review This PR is ready for review. label Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement Changes to an existing feature — removing, adding, or changing parts of it [Package] Premium Analytics [Package] Wp Build Polyfills [Tests] Includes Tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants