Make WordPress Core

Opened 23 months ago

Last modified 5 months ago

#62628 new defect (bug)

Server and client directive negation logic should align

Reported by: jonsurrell Owned by:
Priority: normal Milestone: Awaiting Review
Component: Interactivity API Version: 6.5
Severity: normal Keywords: has-patch
Cc: Focuses:

Description

Interactivity API directives allow for a negation prefix !. Values with this prefix should be negated.

​The server side and ​client side negation logic both rely on rudimentary ! negation. This means that the negation logic depends on PHP and JavaScript behavior which do not always agree and cause differences in server/client rendering of the same data.

For example, with this state:

<?php
wp_interactivity_state(
        'example',
        array(
                'emptyArray' => array(),
                'stringZero' => '0',
        )
);

And the following HTML with directives:

<div data-wp-interactive="example">
        <div data-wp-bind--data-test="!state.emptyArray"></div>
        <div data-wp-bind--data-test="!state.stringZero"></div>
</div>

This is the server render render:

<div data-test="true" data-wp-bind--data-test="!state.emptyArray"></div>
<div data-test="true" data-wp-bind--data-test="!state.stringZero"></div>

While the client renders the following:

<div data-test="false" data-wp-bind--data-test="!state.emptyArray"></div>
<div data-test="false" data-wp-bind--data-test="!state.stringZero"></div>

Change History (4)

#2 @jonsurrell
23 months ago

This resource describes the behavior, "0" and [] may be the only problematic values:

​https://www.php.net/manual/en/language.types.boolean.php

#3 @jonsurrell
16 months ago

  • Keywords needs-patch added

This ticket was mentioned in ​PR #11804 on ​WordPress/wordpress-develop by ​@shreya0shrivastava.


5 months ago
#4

  • Keywords has-patch added; needs-patch removed

The Interactivity API supports a negation prefix ! in directive values. However, the server-side negation logic relies on PHP's native boolean casting, which disagrees with JavaScript on two values:

  • [] (empty array): falsy in PHP, truthy in JavaScript.
  • '0' (string zero): falsy in PHP, truthy in JavaScript.

This causes a mismatch between server and client rendering of the same state, breaking the hydration contract of the Interactivity API.

This fix updates the server-side negation logic in WP_Interactivity_API::evaluate() to use JavaScript-compatible truthiness rules for these two cases, ensuring server and client rendering agree.

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

## Use of AI Tools

Note: See TracTickets for help on using tickets.