diff --git a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php index bc8da9c9b2e7b..506dc4a518b71 100644 --- a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php +++ b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php @@ -1314,6 +1314,14 @@ private function data_wp_router_region_processor( WP_Interactivity_API_Directive if ( 'enter' === $mode && ! $this->has_processed_router_region ) { $this->has_processed_router_region = true; + // Initializes the `state.url` property from the server. + $this->state( + 'core/router', + array( + 'url' => get_self_link(), + ) + ); + // Enqueues as an inline style. wp_register_style( 'wp-interactivity-router-animations', false ); wp_add_inline_style( 'wp-interactivity-router-animations', $this->get_router_animation_styles() ); diff --git a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-router-region.php b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-router-region.php index f5e5e3a62d37c..ee31459855658 100644 --- a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-router-region.php +++ b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-router-region.php @@ -76,6 +76,25 @@ protected function render_wp_footer() { return ob_get_clean(); } + /** + * Processes directives while temporarily replacing the global + * WP_Interactivity_API instance so that global functions like + * `wp_interactivity_state` operate on the test instance. + * + * @param string $html The HTML to process. + * @return string The processed HTML. + */ + protected function process_directives( string $html ): string { + global $wp_interactivity; + $prev = $wp_interactivity; + $wp_interactivity = $this->interactivity; + + $result = $this->interactivity->process_directives( $html ); + + $wp_interactivity = $prev; + return $result; + } + /** * Tests that no elements are added if the `data-wp-router-region` is * missing. @@ -126,4 +145,58 @@ public function test_wp_router_region_adds_loading_bar_region_only_once() { $this->assertTrue( $p->next_tag( $query ) ); $this->assertFalse( $p->next_tag( $query ) ); } + + /** + * Tests that the `data-wp-router-region` directive initializes the + * `core/router` state URL from the server. + * + * @ticket 64649 + * + * @covers ::process_directives + */ + public function test_wp_router_region_initializes_state_url() { + $_SERVER['REQUEST_URI'] = '/test-page/?query=1'; + + $html = '