close
Skip to content

Fix JS translation loading and make all text translatable#582

Merged
dkotter merged 7 commits into
WordPress:developfrom
t-hamano:fix/missing-i18n-strings
May 19, 2026
Merged

Fix JS translation loading and make all text translatable#582
dkotter merged 7 commits into
WordPress:developfrom
t-hamano:fix/missing-i18n-strings

Conversation

@t-hamano
Copy link
Copy Markdown
Contributor

@t-hamano t-hamano commented May 19, 2026

What?

Fixes internationalization (i18n) gaps across several experiments so that user-facing text is fully translatable.

Why?

Three problems were found:

  1. JS translations were not working at all. Strings in JS/TS were wrapped with @wordpress/i18n functions, but wp_set_script_translations() was never called for any enqueued script. As a result every JS-side string rendered in English regardless of the site locale.
  2. Translatable strings were built by hard concatenation. In the Abilities Explorer help tab, each provider description was split into two translatable strings joined by a literal <strong> tag and ": ". Translators could not see the full sentence and could not reorder the markup for their language.
  3. Some user-visible text was never wrapped in a translation function. Toxicity/sentiment badge labels, badge states, an error notice, and JSON validation messages were hardcoded, so they could never be localized and were invisible to the i18n string scanner.

How?

  1. Call wp_set_script_translations() for every script enqueued through Asset_Loader::enqueue_script(). No path is passed because the plugin is distributed on WordPress.org, which auto-delivers translation JSON to wp-content/languages/plugins/.
  2. Make each Abilities Explorer provider description a single translatable string with the <strong> tag inside, escaped with wp_kses() instead of esc_html__().
  3. Wrap the remaining hardcoded user-facing strings (badge states, error notice, JSON validation messages and status titles) with __().

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 4.7
Used for: Auditing the codebase for i18n issues and drafting the fixes. All changes were reviewed and verified by me.

Testing Instructions

  1. Switch the site to the Japanese (ja) locale and make sure the plugin's Japanese translations are installed.
  2. Access http://localhost:8890/wp-admin/update-core.php and download any available translations.
  3. Confirm JS-side strings now translate.

Screenshots

Before

image

After

image

Changelog Entry

Fixed - User-facing text in several experiments is now fully translatable, and JS-side translations are loaded at runtime.

Open WordPress Playground Preview

t-hamano and others added 5 commits May 19, 2026 19:44
User-facing strings in several experiments were rendered without
translation functions, so they could never be localized and were
invisible to the i18n string scanner. Wrap toxicity/sentiment labels,
badge states, error notices, and JSON validation messages with __().

In the Abilities Explorer help tab, each provider description was split
into two translatable strings joined by a literal "<strong>" and ": ".
This prevents translators from reordering the markup for their language.
Make the whole sentence one translatable string with the <strong> tag
inside, escaped via wp_kses.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "Valid" and "Validation Errors" status labels were hardcoded,
leaving them untranslatable. Wrap them with __() so they are exposed
for localization like the surrounding validation messages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Strings in JS/TS files were wrapped with @wordpress/i18n functions, but
without wp_set_script_translations they were never localized at runtime
and always rendered in English. Call it for every enqueued script so the
translation JSON is loaded. No path is passed because the plugin is
distributed on WordPress.org, which auto-delivers translations to
wp-content/languages/plugins/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Use self::HANDLE_PREFIX . $handle directly instead of the
$script_handle local variable, since it was only used in
straightforward calls.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Remove extra alignment whitespace left after a previous handle change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@t-hamano t-hamano changed the title Fix i18n gaps: enable JS translations and remove string concatenation Fix JS translation loading and make all user-facing text translatable May 19, 2026
@t-hamano t-hamano changed the title Fix JS translation loading and make all user-facing text translatable Fix JS translation loading and make all text translatable May 19, 2026
The error notice string fits within the line-length limit, so the
multi-line wrapping is unnecessary. Match the formatting used by the
other __() calls in the file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@t-hamano t-hamano marked this pull request as ready for review May 19, 2026 11:20
@t-hamano t-hamano mentioned this pull request May 19, 2026
42 tasks
@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: t-hamano <wildworks@git.wordpress.org>

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

Since enqueue_script() now calls wp_set_script_translations(), every
enqueued script gains wp-i18n as a dependency. The test expecting empty
deps now fails because wp-i18n is appended even when the asset file
omits dependencies. Adjust the assertion and rename the test to reflect
what it actually verifies: enqueue succeeds for a dependency-less asset
file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment on lines +146 to +147
// wp_set_script_translations() appends wp-i18n to the otherwise empty deps.
$this->assertSame( array( 'wp-i18n' ), wp_scripts()->registered['ai_no-deps']->deps );
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This change is correct, but I'm not entirely confident. There might be a more reasonable way to assert this.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 19, 2026

Codecov Report

❌ Patch coverage is 20.00000% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.41%. Comparing base (396fcc3) to head (34ed4e6).

Files with missing lines Patch % Lines
...udes/Experiments/Abilities_Explorer/Admin_Page.php 0.00% 4 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             develop     #582      +/-   ##
=============================================
- Coverage      71.41%   71.41%   -0.01%     
  Complexity      1158     1158              
=============================================
  Files             67       67              
  Lines           5584     5586       +2     
=============================================
+ Hits            3988     3989       +1     
- Misses          1596     1597       +1     
Flag Coverage Δ
unit 71.41% <20.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@dkotter dkotter added this to the 1.0.0 milestone May 19, 2026
@dkotter dkotter merged commit 1704050 into WordPress:develop May 19, 2026
18 of 20 checks passed
@t-hamano t-hamano deleted the fix/missing-i18n-strings branch May 20, 2026 00:45
simison pushed a commit to simison/ai that referenced this pull request May 25, 2026
)

Fixed - User-facing text in several experiments is now fully translatable, and JS-side translations are loaded at runtime.

Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: dkotter <dkotter@git.wordpress.org>
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