Skip to content

Interactivity API: Resolve the global instance in hook callbacks - #13510

Open
sirreal wants to merge 3 commits into
WordPress:trunkfrom
sirreal:fix/interactivity-hooks-use-global
Open

sirreal wants to merge 3 commits into
WordPress:trunkfrom
sirreal:fix/interactivity-hooks-use-global

Conversation

@sirreal

@sirreal sirreal commented Sep 14, 2026

Copy link
Copy Markdown
Member

Same problem as #13509 for WP_Interactivity_API: add_hooks() and data_wp_router_region_processor() bind callbacks to the instance. After the global is replaced, wp_interactivity_state() writes to the new instance and the filters read the old one.

This adds four procedural functions to interactivity-api.php and registers those instead. Hook names, priorities, and the instance methods are unchanged.

Test: replace the global, set state, apply script_module_data_@wordpress/interactivity. Fails on trunk with empty data. The test file's set_up() now installs its instance as the global; it registered hooks on an instance that was never the global.

Compatibility: Gutenberg lib/interactivity-api.php checks this filter by instance with has_filter() and will add its own filter too. Both set the same strings, so output is unchanged. That shim should be updated or removed.

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

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Fable 5.1, Claude Opus
Used for: code, test, description.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

🤖 Generated with Claude Code

@sirreal
sirreal force-pushed the fix/interactivity-hooks-use-global branch from 513bdc8 to 5e1134c Compare September 14, 2026 07:01
@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.

`WP_Interactivity_API::add_hooks()` registered its filters as `array( $this, 'method' )`, and `data_wp_router_region_processor()` added `array( $this, 'print_router_markup' )` on `wp_footer`. Those callbacks stay bound to the object that was the global when the hooks were added. Replacing the `$wp_interactivity` global later redirects `wp_interactivity_state()` and `wp_interactivity_config()` to the new instance, but the bound callbacks still read the old one, so the printed script module data comes from the wrong instance.

Register procedural functions that delegate to the current global instance, matching how classic scripts and styles register their hooks.

See #66100, #64484.
@sirreal
sirreal force-pushed the fix/interactivity-hooks-use-global branch from 5e1134c to 5fb6a39 Compare September 14, 2026 07:19
Comment thread src/wp-includes/interactivity-api/class-wp-interactivity-api.php Outdated
@sirreal
sirreal marked this pull request as ready for review September 14, 2026 07:41
@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.

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

Props jonsurrell.

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

@sirreal
sirreal requested a review from luisherranz September 14, 2026 07:41
@sirreal

sirreal commented Sep 14, 2026

Copy link
Copy Markdown
Member Author

Ping @DAreRodz for review.

…nction.

`wp_interactivity_print_router_markup()` returns no value and declared no
return type. Declare `: void`.

`wp_interactivity_script_module_data()` and
`wp_interactivity_router_script_module_data()` already declare
`array $data): array`. `wp_interactivity_script_module_attributes()`
stays untyped to match
`WP_Interactivity_API::add_load_on_client_navigation_attribute_to_script_modules()`,
which declares neither a parameter nor a return type.

See #66100.

// Adds the necessary markup to the footer.
add_action( 'wp_footer', array( $this, 'print_router_markup' ) );
add_action( 'wp_footer', 'wp_interactivity_print_router_markup' );

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.

I'm not seeing any back-compat concerns in Veloria: https://veloria.dev/search/307012ac-d787-481a-97ff-1deba5b3122c

add_filter( 'script_module_data_@wordpress/interactivity-router', array( $this, 'filter_script_module_interactivity_router_data' ) );
add_filter( 'wp_script_attributes', array( $this, 'add_load_on_client_navigation_attribute_to_script_modules' ) );
add_filter( 'script_module_data_@wordpress/interactivity', 'wp_interactivity_script_module_data' );
add_filter( 'script_module_data_@wordpress/interactivity-router', 'wp_interactivity_router_script_module_data' );

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.

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