Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
First support for loadOnClientNavigation
  • Loading branch information
luisherranz committed Oct 20, 2025
commit cc8f8c00cb803d7e7b936abf784b26c8abe9b1dd
19 changes: 14 additions & 5 deletions src/wp-includes/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,15 +175,24 @@ function register_block_script_module_id( $metadata, $field_name, $index = 0 ) {
$block_version = isset( $metadata['version'] ) ? $metadata['version'] : false;
$module_version = isset( $module_asset['version'] ) ? $module_asset['version'] : $block_version;

// Blocks using the Interactivity API are server-side rendered, so they are by design not in the critical rendering path and should be deprioritized.
$supports_interactivity_true = isset( $block_type->supports['interactivity'] ) && true === $block_type->supports['interactivity'];
$is_interactive = $supports_interactivity_true || ( isset( $block_type->supports['interactivity']['interactive'] ) && true === $block_type->supports['interactivity']['interactive'] );
$supports_client_navigation = $supports_interactivity_true || ( isset( $block_type->supports['interactivity']['clientNavigation'] ) && true === $block_type->supports['interactivity']['clientNavigation'] );

$args = array();
if (
( isset( $metadata['supports']['interactivity'] ) && true === $metadata['supports']['interactivity'] ) ||
( isset( $metadata['supports']['interactivity']['interactive'] ) && true === $metadata['supports']['interactivity']['interactive'] )
) {

// Blocks using the Interactivity API are server-side rendered, so they are
// by design not in the critical rendering path and should be deprioritized.
if ( $is_interactive ) {
$args['fetchpriority'] = 'low';
}

// Blocks using the Interactivity API that support client-side navigation
// must be marked as such in their script modules.
if ( $is_interactive && $supports_client_navigation ) {
wp_interactivity()->add_client_navigation_support_to_script_module( $module_id );
}

wp_register_script_module(
$module_id,
$module_uri,
Expand Down
49 changes: 49 additions & 0 deletions src/wp-includes/interactivity-api/class-wp-interactivity-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@
*/
private $has_processed_router_region = false;

/**
* Set of script modules that can be loaded after client-side navigation.
*

Check failure on line 90 in src/wp-includes/interactivity-api/class-wp-interactivity-api.php

View workflow job for this annotation

GitHub Actions / Coding standards / PHP checks

Whitespace found at end of line
* @since 6.9.0
* @var array<string, bool>
*/
private $script_modules_that_can_load_on_client_navigation = array();

/**
* Stack of namespaces defined by `data-wp-interactive` directives, in
* the order they are processed.
Expand Down Expand Up @@ -371,10 +379,51 @@
* Adds the necessary hooks for the Interactivity API.
*
* @since 6.5.0
* @since 6.9.0 Adds support for client-side navigation in script modules.
*/
public function add_hooks() {
add_filter( 'script_module_data_@wordpress/interactivity', array( $this, 'filter_script_module_interactivity_data' ) );
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' ), 10, 1 );
}

/**
* Adds the `data-wp-router-options` attribute to script modules that
* support client-side navigation.
*
* This method filters the script attributes to include loading instructions
* for the Interactivity API router, indicating which modules can be loaded
* during client-side navigation.
*
* @since 6.9.0
*
* @param array $attributes The script tag attributes.
* @return array The modified script tag attributes.
*/
public function add_load_on_client_navigation_attribute_to_script_modules( $attributes ) {
if (
isset( $attributes['type'] ) && $attributes['type'] === 'module' && isset( $attributes['id'] )

Check failure on line 405 in src/wp-includes/interactivity-api/class-wp-interactivity-api.php

View workflow job for this annotation

GitHub Actions / Coding standards / PHP checks

Use Yoda Condition checks, you must.
&& array_key_exists( $attributes['id'], $this->script_modules_that_can_load_on_client_navigation )
) {
$attributes['data-wp-router-options'] = wp_json_encode( array( 'loadOnClientNavigation' => true ) );
}
return $attributes;
}

/**
* Marks a script module as compatible with client-side navigation.
*

Check failure on line 415 in src/wp-includes/interactivity-api/class-wp-interactivity-api.php

View workflow job for this annotation

GitHub Actions / Coding standards / PHP checks

Whitespace found at end of line
* This method registers a script module to be loaded during client-side
* navigation in the Interactivity API router. Script modules marked with
* this method will have the `loadOnClientNavigation` option enabled in the
* `data-wp-router-options` directive.
*
* @since 6.9.0
*
* @param string $script_module_id The script module identifier.
*/
public function add_client_navigation_support_to_script_module( $script_module_id ) {
$this->script_modules_that_can_load_on_client_navigation[ $script_module_id . '-js-module' ] = true;
}

/**
Expand Down
5 changes: 5 additions & 0 deletions src/wp-includes/script-modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,11 @@ function wp_default_script_modules() {
$args['fetchpriority'] = 'low';
}

// Marks all Core blocks as compatible with client-side navigation.
if ( str_starts_with( $script_module_id, '@wordpress/block-library' ) ) {
wp_interactivity()->add_client_navigation_support_to_script_module( $script_module_id );
}

$path = includes_url( "js/dist/script-modules/{$file_name}" );
wp_register_script_module( $script_module_id, $path, $script_module_data['dependencies'], $script_module_data['version'], $args );
}
Expand Down
Loading