Title: Interactivity API in 6.5
Author: Carlos Bravo
Published: March 4, 2024
Last modified: May 12, 2025

---

 [  ](https://profiles.wordpress.org/cbravobernal/) [Carlos Bravo](https://profiles.wordpress.org/cbravobernal/)
2:57 pm _on_ March 4, 2024     
Tags: [6-5 ( 76 )](https://make.wordpress.org/core/tag/6-5/),
[dev-notes ( 648 )](https://make.wordpress.org/core/tag/dev-notes/), [dev-notes-6.5 ( 15 )](https://make.wordpress.org/core/tag/dev-notes-6-5/),
[interactivity API ( 11 )](https://make.wordpress.org/core/tag/interactivity-api/)

# Interactivity API in 6.5

The Interactivity APIAPI An API or Application Programming Interface is a software
intermediary that allows programs to interact with each other and share data in 
limited, clearly defined ways. provides a standard way for developers to add interactions
to the frontend of their blocks.

This standard aims to make it **easier for developers to create rich, interactive
user experiences**, from simple cases like counters or pop-ups to more complex features
like instant page navigation, instant search, carts, or checkouts.

Blocks can share data, actions, and callbacks between them. This makes communication
between blocks simpler and less error-prone. For example, clicking on an “add to
cart” blockBlock Block is the abstract term used to describe units of markup that,
composed together, form the content or layout of a webpage using the WordPress editor.
The idea combines concepts of what in the past may have achieved with shortcodes,
custom HTML, and embed discovery into a single consistent API and user experience.
can seamlessly update a separate “cart” block.

To understand better the reasoning behind it, you can take a look at [the original proposal](https://make.wordpress.org/core/2023/03/30/proposal-the-interactivity-api-a-better-developer-experience-in-building-interactive-blocks/),
where it is explained in more detail.

More information about it can be found in the [merge announcement](https://make.wordpress.org/core/2024/02/19/merge-announcement-interactivity-api/),
the [status update post](https://make.wordpress.org/core/2023/08/15/status-update-on-the-interactivity-api/),
and the [Trac ticket](https://core.trac.wordpress.org/ticket/60356) for the Interactivity
API.

This dev notedev note Each important change in WordPress Core is documented in a
developers note, (usually called dev note). Good dev notes generally include a description
of the change, the decision that led to this change, and a description of how developers
are supposed to work with that change. Dev notes are published on Make/Core blog
during the beta phase of WordPress release cycle. Publishing dev notes is particularly
important when plugin/theme authors and WordPress developers need to be aware of
those changes.In general, all dev notes are compiled into a Field Guide at the beginning
of the release candidate phase. covers the APIs included in 6.5 and how to use the
Interactivity API.

## **How to create interactions using the Interactivity API**

It’s important to highlight that **the block creation ****_workflow_**** doesn’t
change**.

Until now, WordPress has been intentionally unopinionated about the different solutions
used on the frontend of blocks. The Interactivity API changes that. It adds **a 
new standard way to easily add frontend interactivity to blocks** while the APIs
handling the Block Editor remain the same.

You need first to declare its compatibility with the API by adding the interactivity
property inside  supports, in the `block.json` file:

    ```notranslate
    "supports": {
        "interactivity": true
    },
    ```

Refer to the [Block Editor handbook](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#interactivity)
to get a more detailed description of the `interactivity` support property.

The Interactivity API script requires using [the new script modules coming in WordPress 6.5](https://make.wordpress.org/core/2024/03/04/script-modules-in-6-5/),
so blocks should enqueue the JavaScriptJavaScript JavaScript or JS is an object-
oriented computer programming language commonly used to create interactive effects
within web browsers. WordPress makes extensive use of JS for a better user experience.
While PHP is executed on the server, JS executes within a user’s browser. [https://www.javascript.com](https://www.javascript.com/)
by using viewScriptModule:

    ```notranslate
    // block.json
    {
       ...
       "viewScriptModule": "file:./view.js"
    }
    ```

_You can easily scaffold and test an interactive block following_[_ __this quick start guide_](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/#quick-start-guide)_,
which explains how to use a CLICLI Command Line Interface. Terminal (Bash) in Mac,
Command Prompt in Windows, or WP-CLI for WordPress. command to speed up this process._

With that in mind, in order to add interactivity to blocks powered by the Interactivity
API, developers would need to:

 1. Add directives to the markup to add specific interactions to the block.
 2. Create a store with the logic (state, actions, or callbacks) for interactivity.

Let’s use a simple example to explain it: a button that shows and hides some text.
Let’s also send a message in the console whenever the button is hidden or revealed.

### **1. Add the directives**

Directives are custom attributes that are added to the markup of your block to add
interactions to its DOM elements. They are placed in the render.php file (for dynamic
blocks).

The very first step is to add the `data-wp-interactive` directive. This is used 
to “activate” the Interactivity API in a DOM element and its children, and its value
must be the unique namespace of your pluginPlugin A plugin is a piece of software
containing a group of functions that can be added to a WordPress website. They can
extend functionality or add new features to your WordPress websites. WordPress plugins
are written in the PHP programming language and integrate seamlessly with WordPress.
These can be free in the WordPress.org Plugin Directory [https://wordpress.org/plugins/](https://wordpress.org/plugins/)
or can be cost-based plugin from a third-party. or block:

    ```notranslate
    <div data-wp-interactive="myPlugin">
        <!-- Interactivity API zone -->
    </div>
    ```

The rest of the directives can be added with the desired interactions.

    ```notranslate
    // render.php
    $context = array('isOpen' => false);
    <div
      data-wp-interactive='myPlugin'
      data-wp-watch="callbacks.logIsOpen"
    >
      <button>
        Toggle
      </button>
      <p id="p-1">
        This element is now visible!
      </p>
    </div>
    ```

Additionally, directives can also be injected dynamically using the[ HTML Tag Processor](https://make.wordpress.org/core/2023/03/07/introducing-the-html-api-in-wordpress-6-2).

Don’t worry if you don’t understand how it works yet. So far, the important part
is that the example above uses directives like `wp-on` and `wp-bind` to add interactivity
to the HTMLHTML HyperText Markup Language. The semantic scripting language primarily
used for outputting content in web browsers.. This is the list of directives available
in WordPress 6.5:

_You can find a deeper explanation of each directive and examples of how to use 
it in the relevant links._

 * [wp-interactive](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-interactive):
   This attribute **must be set** to the unique identifier of your plugin or block
   in order for it to use the Interactivity API.
 * [wp-context](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-context):
   It provides a **local** state available to a specific HTML node and its children.
   It accepts stringified JSONJSON JSON, or JavaScript Object Notation, is a minimal,
   readable format for structuring data. It is used primarily to transmit data between
   a server and web application, as an alternative to XML. as a value. It’s recommended
   to use `wp_interactivity_data_wp_context()` to set it in PHPPHP The web scripting
   language in which WordPress is primarily architected. WordPress requires PHP 
   7.4 or higher.
 * [wp-bind](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-bind):
   It allows HTML attributes to be set on elements based on a boolean or string 
   value. It follows the syntax `data-wp-bind--[attribute]`. (like `data-wp-bind--
   value`)
 * [wp-class](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-class):
   It adds or removes a class to an HTML element, depending on a boolean value. 
   It follows the syntax `data-wp-class--[classname]`.
 * [wp-style](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-style):
   It adds or removes inline style to an HTML element, depending on its value. It
   follows the syntax `data-wp-style--[css-property].`
 * [wp-text](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-text):
   It sets the inner text of an HTML element. It only accepts strings as the parameter.
 * [wp-on](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-on):
   It runs code on dispatched DOM events like click or keyup. Its syntax is `data-
   wp-on--[event]` (like `data-wp-on--click` or `data-wp-on--keyup`).
 * [wp-on-window](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-on-window):
   It allows to attach global window events like resize, copy, focus and then execute
   a defined callback when those happen. Its syntax is `data-wp-on-window--[window-
   event]` (like `data-wp-on-window--resize` or `data-wp-on-window--languagechange`).
 * [wp-on-document](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-on-document):
   It allows to attach global document events like scroll, mousemove, keydown and
   then execute a defined callback when those happen. Its syntax is `data-wp-on-
   document--[document-event]` (like `data-wp-on-document--keydown` or `data-wp-
   on-document--selectionchange`).
 * [wp-watch](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-watch):
   It runs a callback **when the node is created and runs it again when the state
   or context changes**.
 * [wp-init](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-init):
   It runs a callback **only when the node is created**.
 * [wp-run](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-run):
   It runs the passed callback **during node’s render execution**.
 * [wp-key](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-key):
   It assigns a unique key to an element to help the Interactivity API identify 
   it when iterating through arrays of elements.
 * [wp-each](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-each):
   It is intended to render a list of elements.
 * [wp-each-child](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#wp-each-child):
   Ensures hydration works as expected, is added automatically on the server processing
   of wp-each directive.

### **2. Create the store**

The store is used to create the logic that will link the directives with the data
used inside that logic.

All stores are referenced by a unique namespace, separating the logic and avoiding
name collisions between different store properties and functions.

If there are multiple stores defined with the same namespace, they will be merged
into a single store.

The store is usually created in the view.js file of each block, although the state
can be initialized in the backend, for example, [in the render file of the block.](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#render)

The state is a global object, available to all HTML nodes of the page. It is defined
by the `store()` function. If you need a local state for just a node and its children,
check the context definition.

The object can accept any property, in order to keep consistency between projects,
this convention is recommended.

 * **State**: Defines data available to the HTML nodes of the page. Properties inside
   the state will be available globally. If you need to edit them, the recommended
   way is by using getters.
    - **Derived State.** If you need a modified version of any state property, [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)
      are the recommended approach (more on deriving state below).
 * **Actions**: Usually triggered by the `data-wp-on` directive (using event listeners).
 * **Callbacks**: Automatically reactReact React is a JavaScript library that makes
   it easy to reason about, construct, and maintain stateless and stateful user 
   interfaces. [https://reactjs.org](https://reactjs.org/) to state changes. Usually
   triggered by `data-wp-on-window`, `data-wp-on-document` or `data-wp-init` directives.

Returning to our example, this could be a simple store in one block, a global state
has been added for having a complete sample of how a store could look like.

    ```notranslate
    // view.js
    import { store, getContext } from "@wordpress/interactivity";

    const { state } = store( 'myPlugin', {
     state: {
      likes: 0,
      getDoubleLikes() {
        return 2 * state.likes;
      }
     },
      actions: {
        toggle: () => {
          const context = getContext();
          context.isOpen = !context.isOpen;
        },
      },
      callbacks: {
        logIsOpen: () => {
          const context = getContext();
          // Log the value of `isOpen` each time it changes.
          console.log(`Is open: ${context.isOpen}`);
        },
      },
    });
    ```

There can be cases where only actions and callbacks are defined in the store.

DOM elements are connected to data stored in the state and context through directives.
If data in the state or context change directives will react to those changes, updating
the DOM accordingly (see[ diagram](https://excalidraw.com/#json=T4meh6lltJh6TCX51NTIu,DmIhxYSGFTL_ywZFbsmuSw)).

![](https://lh7-us.googleusercontent.com/G33N5-1OIQxE17VWPbBp966anMvtfGzYuaEvcmetVe-
KH3jL7ZlfV79m0i6i9jaS8CInt3la3DfTr_dObamrrlnp07OP8Qa7NK1SFaJccvQal5QQxA_66NCL9qH8-
6edOJFTzPvd0Y-iUV-hHc9mCZs)

When creating the store, there are some important things to be aware of:

#### **Using derived state**

Derived state uses [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)
to return a computed version of the state. It can access both state and context.

    ```notranslate
    // view.js

    const { state } = store( "myPlugin", {
      state: {
        amount: 34,
        defaultCurrency: 'EUR',
        currencyExchange: {
          USD: 1.1,
          GBP: 0.85,
        },
        get amountInUSD() {
          return state.currencyExchange[ 'USD' ] * state.amount,
        },
        get amountInGBP() {
          return state.currencyExchange[ 'GBP' ] * state.amount,
        },
      },
    } );
    ```

#### **Accessing the store**_ _**by destructuring**

The store contains all the store properties, like state, actions, or callbacks. 
They are returned by the `store()` call, so you can access them by destructuring
it:

    ```notranslate
    const { state, actions, callbacks } = store( "myPlugin", {
      // ...
    } );
    ```

Note that context is not part of the store and is accessed through the `getContext`
function.

If you want to take a deeper view about how the `store()` function works, feel free
to check the function documentation [here](https://github.com/WordPress/gutenberg/blob/8cb23964d58f3ce5cf6ae1b6f967a4b8d4939a8e/packages/interactivity/src/store.ts#L208).

#### **Async actions**

Async actions should use [generator functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*)
instead of async/await or promises. The Interactivity API needs to be able to track
async behavior in order to restore the proper scope. Otherwise, `getContext` may
return stale values if it was updated concurrently with the async operation. Instead
of awaiting the promise, yield it from the generator function, and the Interactivity
API will handle awaiting its completion.

So, instead of:

    ```javascript
    const { state } = store("myPlugin", {
      state: {
        get isOpen() {
          return getContext().isOpen;
        },
      },
      actions: {
        someAction: async () => {
          state.isOpen; // This is the expected context.
          await longDelay();
          state.isOpen; // This may not get the proper context unless it's properly restored.
        },
      },
    });

    function longDelay() {
      return new Promise( ( resolve ) => {
        setTimeout( () => resolve(), 3_000 );
      } );
    }
    ```

The store should be:

    ```javascript
    const { state } = store("myPlugin", {
      state: {
        get isOpen() {
          return getContext().isOpen;
        },
      },
      actions: {
        someAction: function* () {
          state.isOpen; // This is the expected context.
          yield longDelay(); // With generators, the caller controls when to resume this function.
          state.isOpen; // This context is correct because the scope was restored before resuming after the yield.
        },
      },
    });

    function longDelay() {
      return new Promise( ( resolve ) => {
        setTimeout( () => resolve(), 3_000 );
      } );
    }
    ```

If you want to take a deeper look at the example, check the [API reference](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/).

---

### **Working with other namespaces**

Interactive blocks can share data between them, unless they are private stores.

#### **Directives**

In order to access the store of a different namespace in a directive, add the namespace
before the directive value. For example:

    ```language-markup
    <!-- This accesses the current store -->
    <div data-wp-bind--id="state.text"></div>
    <!-- This accesses the "otherPlugin" store -->
    <button data-wp-bind--id="otherPlugin::state.text">>Button</button>
    ```

### **Context**

Context from a different namespace can be accessed by providing the desired namespace
as an argument to `getContext( namespace )`:

    ```javascript
    import { getContext } from "@wordpress/interactivity";

    const otherPluginContext = getContext( "otherPlugin" );
    ```

### **Store**

Like context, different stores can be accessed by passing the desired namespace 
as an argument: 

    ```javascript
    const { state: otherState, actions: otherActions } = store( "otherPlugin" );
    ```

#### **Private stores**

A store can be “locked” to prevent its content from being accessed from other namespaces.
To do so, set the lock option to true in the store() call, like in the example below.
When the lock is set, subsequent executions of store() with the same locked namespace
will throw an error, meaning that the namespace can only be accessed where its reference
was returned from the first store() call. This is especially useful for developers
who want to hide part of their plugin stores so it doesn’t become accessible for
extenders.

    ```javascript
    const { state } = store("myPlugin/private", {
      state: {
          messages: [ "private message" ]
        } 
      },
      { lock: true }
    );

    // The following call throws an Error!
    store( "myPlugin/private", { /* store part */ } );
    ```

There is also a way to unlock private stores: instead of passing a boolean, you 
can use a string as the lock value. Such a string can then be used in subsequent
store() calls to the same namespace to unlock its content. Only the code with the
lock string will be able to access the protected store. This is useful for complex
stores defined across multiple files.

    ```javascript
    const { state } = store("myPlugin/private", {
      state: {
          messages: [ "private message" ]
        }
      },
      { lock: PRIVATE_LOCK }
    );

    // The following call works as expected.
    store( "myPlugin/private", { /* store part */ }, { lock: PRIVATE_LOCK } );
    ```

### **Interactivity API client methods**

The following methods are for use in JavaScript and are provided by the wordpress/
interactivity script module available in WordPress 6.5.

#### **getContext()**

The context defined with the `data-wp-context` attribute can be retrieved with the
getContext function:

    ```javascript
    const { state } = store( "myPlugin", {
      actions: {
        someAction() {
          const context = getContext();
          const otherPluginContext = getContext( 'otherPlugin' );
          // ...
        }
      }
    } );
    ```

[Handbook description.](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#store-client-methods)

#### **getElement()**

Retrieves a representation of the element where a function from the store is being
evaluated. This representation is read-only, and contains a reference to the DOM
element and its attributes.

[Handbook description.](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-interactivity/packages-interactivity-api-reference/#store-client-methods)

#### **getConfig()**

Retrieves a configuration object that was previously defined in the server via `
wp_interactivity_config()` function.

Configuration is immutable on the client, it cannot be modified. You can get an 
example [later in this document.](https://make.wordpress.org/core/2024/03/04/interactivity-api-dev-note/?output_format=md#wp-interactivity-config)

#### **store()**

Creates the store used to link the data and actions with their respective directives.
Check the main section for more information.

#### **withScope()**

Actions can depend on the scope when they are called, e.g., when you call `getContext()`
or `getElement()`.

When the Interactivity API runtime execute callbacks, the scope is set automatically.
However, if you call an action from a callback that is not executed by the runtime,
like in a `setInterval()` callback, you need to ensure that the scope is properly
set. Use the `withScope()` function to ensure the scope is properly set in these
cases.

An example, where `actions.nextImage` would trigger an undefined error without the
wrapper:

    ```javascript
    store('mySliderPlugin', {
    	callbacks: {
    		initSlideShow: () => {
    		    setInterval(
    				withScope( () => {
    					actions.nextImage();
    				} ),
    				3_000
    			);
    		}
    	},
    })
    ```

### **Interactivity API server functions**

These are the PHP functions the Interactivity API includes:

#### **wp_interactivity_state( $store_namespace, $state )**

It is used to initialize the state on the server and ensure that the HTML sent by
it, and the HTML after the client hydration are the same. And it also allows you
to use any WordPress API like coreCore Core is the set of software required to run
WordPress. The Core Development Team builds WordPress. translations.

    ```php
    // render.php

    wp_interactivity_state( "movies", array(
          "1" => array(
            "id" => "123-abc",
            "movieName" => __("someMovieName", "textdomain")
          ),
    ) );
    ```

It receives two arguments, a string with the namespace that will be used as a reference
and an [associative array](https://www.php.net/manual/en/language.types.array.php)
containing the values.

The state defined on this function gets merged with the stores defined in the view.
js files.

#### **wp_interactivity_data_wp_context( $context, $_store\_namespace _)**

Generates a `data-wp-context` attribute ready to be server side rendered. This function
escapes the array to prevent external attacks, apart from any error that may appear
when writing JSON strings manually.

`$context` is an array containing the keys and values of the context.

`$_store\_namespace_` allows referencing different stores, and is empty by default.

    ```wp-block-code
    <?php
     $context = wp_interactivity_data_wp_context(
      array(
        'post_id' => get_the_ID(),
        'show' => true,
      )
     )
    ?>
    <div <?php echo $context ?> >
      My interactive div
    </div>
    ```

Will return

    ```wp-block-code
    <div data-wp-context="{"post_id":1,"show":true}">
      My interactive div
    </div>
    ```

#### **wp_interactivity_config( $store_namespace, $config )**

Sets or gets configuration for an interactivity store. An immutable copy of the 
configuration can be read by the client.

Consider config as a global setting that can affect the full site and won’t be updated
on client interactions. For example, determining if a site can handle client-side
navigation or not.

    ```php
    <?php
    wp_interactivity_config( 'myPlugin', array( 'setting' => true ) );
     $config = wp_interactivity_config( 'myPlugin' );
    ?>
    <div>
      My interactive div
    </div>
    ```

This config can be retrieved in the client:

    ```wp-block-code
    // view.js

    import { getConfig } from '@wordpress/interactivity';

    const { setting } = getConfig('myPlugin');
    console.log( 'setting => ', setting);
    ```

#### **wp_interactivity_process_directives( $html )**

Processes directives within HTML content, updating the markup where necessary.

This is the core functionality of the Interactivity API. It’s public so that any
HTML can be processed, not just blocks.

For blocks with `supports.interactivity,` directives are automatically processed.
Developers do not need to call **wp_interactivity_process_directives** in this case.

    ```wp-block-code
    <?php
    $html_content = '<div data-wp-text="myPlugin::state.message"></div>';

    wp_interactivity_state( 'myPlugin', array( 'message' => 'hello world!' ) );

    // Process directives in HTML content.
    $processed_html = wp_interactivity_process_directives( $html_content );

    // output: <div data-wp-text="myPlugin::state.message">hello world!</div>
    ```

### Relevant links

 * [Showcase](https://github.com/WordPress/gutenberg/discussions/55642)
 * [Store API proposal](https://github.com/WordPress/gutenberg/discussions/53586)

Props to [@gziolo](https://profiles.wordpress.org/gziolo/), [@darerodz](https://profiles.wordpress.org/darerodz/),
[@santosguillamot](https://profiles.wordpress.org/santosguillamot/), [@luisherranz](https://profiles.wordpress.org/luisherranz/)
and [@jonsurrell](https://profiles.wordpress.org/jonsurrell/) for technical review.

Props to [@leonnugraha](https://profiles.wordpress.org/leonnugraha/) for copy review.

[#6-5](https://make.wordpress.org/core/tag/6-5/), [#dev-notes](https://make.wordpress.org/core/tag/dev-notes/),
[#dev-notes-6-5](https://make.wordpress.org/core/tag/dev-notes-6-5/), [#interactivity-api](https://make.wordpress.org/core/tag/interactivity-api/)

### Share this:

 * [  Threads ](https://make.wordpress.org/core/2024/03/04/interactivity-api-dev-note/?share=threads)
 * [  Mastodon ](https://make.wordpress.org/core/2024/03/04/interactivity-api-dev-note/?share=mastodon)
 * [  Bluesky ](https://make.wordpress.org/core/2024/03/04/interactivity-api-dev-note/?share=bluesky)
 * [  X ](https://make.wordpress.org/core/2024/03/04/interactivity-api-dev-note/?share=x)
 * [  Facebook ](https://make.wordpress.org/core/2024/03/04/interactivity-api-dev-note/?share=facebook)
 * [  LinkedIn ](https://make.wordpress.org/core/2024/03/04/interactivity-api-dev-note/?share=linkedin)

 1.  ![](https://secure.gravatar.com/avatar/eb2dbdff6acddf1b814e99b556bfd13ab446de158213b57c54cafbfaa26dfdc4?
     s=32&d=mm&r=g)
 2.   [Justin Sainton](https://profiles.wordpress.org/justinsainton/)  5:20 pm _on_
     March 4, 2024
 3.  Under the `wp_interactivity_data_wp_context` section, the `$context` parameter
     needs to be passed to the function.
 4.   * ![](https://secure.gravatar.com/avatar/4b66853c11bd212a5e7fc757d5a239131f300e8bbdcce8c4327c63023f8221d3?
        s=32&d=mm&r=g)
      *  [Carlos Bravo](https://profiles.wordpress.org/cbravobernal/)  8:26 pm _on_
        March 4, 2024
      * Fixed, thanks!
 5.  ![](https://secure.gravatar.com/avatar/2915e1013f968e0a0272b4d95ca3296049b5e4e53ae8a3cad515780e59b69adc?
     s=32&d=mm&r=g)
 6.   [jakeparis](https://profiles.wordpress.org/jakeparis/)  9:37 pm _on_ March 13,
     2024
 7.  I’ve found I need to add a ` –experimental-modules` flag to my `wp-scripts` command
     in order for this to work.
 8.   * ![](https://secure.gravatar.com/avatar/4b66853c11bd212a5e7fc757d5a239131f300e8bbdcce8c4327c63023f8221d3?
        s=32&d=mm&r=g)
      *  [Carlos Bravo](https://profiles.wordpress.org/cbravobernal/)  8:14 pm _on_
        April 8, 2024
      * Yes, Interactivity APIAPI An API or Application Programming Interface is a 
        software intermediary that allows programs to interact with each other and 
        share data in limited, clearly defined ways. scripts require modules, an example
        of the package.jsonJSON JSON, or JavaScript Object Notation, is a minimal, 
        readable format for structuring data. It is used primarily to transmit data
        between a server and web application, as an alternative to XML. scripts could
        be:
      *     ```notranslate
              "scripts": {
                "build": "wp-scripts build --experimental-modules",
                "start": "wp-scripts start --experimental-modules",
                "env": "wp-env",
                ...etc
            }
            ```
        
 9.  ![](https://secure.gravatar.com/avatar/11177b397354c97025f395594f49e10041be4497df46e5d8b1f5b7ca4b063a3a?
     s=32&d=mm&r=g)
 10.  [Phil Johnston](https://profiles.wordpress.org/johnstonphilip/)  1:02 am _on_
     March 18, 2024
 11. Should those htmlHTML HyperText Markup Language. The semantic scripting language
     primarily used for outputting content in web browsers. attributes be escaped with
     esc_html?
 12.  * ![](https://secure.gravatar.com/avatar/11177b397354c97025f395594f49e10041be4497df46e5d8b1f5b7ca4b063a3a?
        s=32&d=mm&r=g)
      *  [Phil Johnston](https://profiles.wordpress.org/johnstonphilip/)  1:02 am _on_
        March 18, 2024
      * Or rather, esc_attr?
         - ![](https://secure.gravatar.com/avatar/4b66853c11bd212a5e7fc757d5a239131f300e8bbdcce8c4327c63023f8221d3?
           s=32&d=mm&r=g)
         -  [Carlos Bravo](https://profiles.wordpress.org/cbravobernal/)  8:12 pm _on_
           April 8, 2024
         - `data-wp` are expected to be strings. Otherwise the APIAPI An API or Application
           Programming Interface is a software intermediary that allows programs to
           interact with each other and share data in limited, clearly defined ways.
           won’t relate them to their respective properties of its stores.
         - If you are getting those values from any external input (I cannot think 
           about one example of doing that right now), should be escaped with `esc_attr`
           as you mentioned.
 13. ![](https://secure.gravatar.com/avatar/00ce0f258fcc5e5d29897a5e81316009713e9104cfaf49f481c5bce3f81c7cb1?
     s=32&d=mm&r=g)
 14.  [John Russell](https://profiles.wordpress.org/laubsterboy/)  12:07 am _on_ April
     4, 2024
 15. This is very exciting! Any idea how you would approach/structure something like
     a mega menu (or a generic modal) where the button to open the menu/modal, or the
     modal itself, may not necessarily be a descendant of the container element with
     the data-wp-interactive=”myPlugin” attribute? Two separate blocks, one for the
     open/toggle button and one for the modal?
 16.  * ![](https://secure.gravatar.com/avatar/4b66853c11bd212a5e7fc757d5a239131f300e8bbdcce8c4327c63023f8221d3?
        s=32&d=mm&r=g)
      *  [Carlos Bravo](https://profiles.wordpress.org/cbravobernal/)  8:36 pm _on_
        April 8, 2024
      * Thanks!
      * If you need a modal without being descendant of any container, you can use 
        the global state for your pluginPlugin A plugin is a piece of software containing
        a group of functions that can be added to a WordPress website. They can extend
        functionality or add new features to your WordPress websites. WordPress plugins
        are written in the PHP programming language and integrate seamlessly with WordPress.
        These can be free in the WordPress.org Plugin Directory [https://wordpress.org/plugins/](https://wordpress.org/plugins/)
        or can be cost-based plugin from a third-party. store.
      * PHPPHP The web scripting language in which WordPress is primarily architected.
        WordPress requires PHP 7.4 or higher:
      *     ```notranslate
            <?php
             wp_interactivity_state( 'myPlugin', array( 'isModalOpen' => false ) );
            ?>
            <div id="modal" data-wp-interactive="myPlugin" data-wp-class--is-modal-open="state.isModalOpen">Modal</div>
            <button data-wp-interactive="myPlugin" data-wp-on--click="actions.toggleModal">Toggle Modal</button>
            ```
        
      * JSJS JavaScript, a web scripting language typically executed in the browser.
        Often used for advanced user interfaces and behaviors.:
      *     ```notranslate
            /**
             * WordPress dependencies
             */
            import { store } from "@wordpress/interactivity";
        
            const { state } = store("myPlugin", {
              actions: {
                toggleModal() {
                  state.isModalOpen = !state.isModalOpen;
                },
              },
            });
            ```
        
      * CSSCSS Cascading Style Sheets.:
      *     ```notranslate
            /**
             * The following styles get applied both on the front of your site
             * and in the editor.
             *
             * Replace them with your own styles or remove the file completely.
             */
        
            #modal {
            	display: none;
            }
            #modal.is-modal-open {
            	display: block;
            }
            ```
        
      * Maybe is not the best example to do a modal with this CSS, but you can get 
        an idea of what you can do without the requirement of being dependants.
      * Between using one or two blocks, I guess it will depend on the experience you
        want to have in the editor. But mind that the user may add several buttons 
        or modals inside the same page, so you will need to relate them in order not
        to open all of them at the same time or with different buttons.
      * Also, this is a quick example, so it may not have the best HTMLHTML HyperText
        Markup Language. The semantic scripting language primarily used for outputting
        content in web browsers. structure.
      * There is a showcase where different developers are sharing their Interactivity
        APIAPI An API or Application Programming Interface is a software intermediary
        that allows programs to interact with each other and share data in limited,
        clearly defined ways. projects.
         [https://github.com/WordPress/gutenberg/discussions/55642](https://github.com/WordPress/gutenberg/discussions/55642)
      * I also recommend following the Developer’s blogblog (versus network, site):
        
        [https://developer.wordpress.org/news](https://developer.wordpress.org/news)
 17. ![](https://secure.gravatar.com/avatar/807531d45b363a83a468ef8e59e84ad0b060fdcf7b39aa16d0e7dfa312c2e75b?
     s=32&d=mm&r=g)
 18.  [arneyfrazer](https://profiles.wordpress.org/arneyfrazer/)  8:48 am _on_ April
     11, 2024
 19. Can the Interactivity be enabled for elements rendered on the front-end via JSJS
     JavaScript, a web scripting language typically executed in the browser. Often 
     used for advanced user interfaces and behaviors.? For example, using a front-end
     template ( wp.template() ) and rendering a new node from this template?
 20.  * ![](https://secure.gravatar.com/avatar/4b66853c11bd212a5e7fc757d5a239131f300e8bbdcce8c4327c63023f8221d3?
        s=32&d=mm&r=g)
      *  [Carlos Bravo](https://profiles.wordpress.org/cbravobernal/)  8:45 am _on_
        April 22, 2024
      * I’m afraid that the init function that runs the Interactivity is only called
        on ‘DOMContentLoaded’ and is not exported, so you would not be available to
        call it after creating those nodes.
 21. ![](https://secure.gravatar.com/avatar/25815eeefadffbd4b82bd2c406e115e95723926e7b4f2fa67502f3baf5de2b29?
     s=32&d=mm&r=g)
 22.  [Tauno Hanni](https://profiles.wordpress.org/taunoh/)  8:48 pm _on_ June 10, 
     2024
 23. Fantastic! 🎉 I’ve been diving into the APIAPI An API or Application Programming
     Interface is a software intermediary that allows programs to interact with each
     other and share data in limited, clearly defined ways., and it’s incredibly cool.
     I’ve been experimenting with JavaScriptJavaScript JavaScript or JS is an object-
     oriented computer programming language commonly used to create interactive effects
     within web browsers. WordPress makes extensive use of JS for a better user experience.
     While PHP is executed on the server, JS executes within a user’s browser.
      [https://www.javascript.com](https://www.javascript.com/)
     generators to test async functions, and everything works as expected when I use`
     npm run start`. However, I noticed an issue when running `npm run build` – things
     don’t work as expected. It seems that my function is not triggered at all. Any
     insights on this would be greatly appreciated 🙂

Comments are closed.

# Post navigation

[← Script Modules in 6.5](https://make.wordpress.org/core/2024/03/04/script-modules-in-6-5/)

[Updates to the HTML API in 6.5 →](https://make.wordpress.org/core/2024/03/04/updates-to-the-html-api-in-6-5/)