wp-interactivity-api
wordpress/agent-skills
Build and debug WordPress Interactivity API features with directives, store state, and hydration.
What is wp-interactivity-api?
This skill helps you work with WordPress Interactivity API—the framework for adding interactivity to blocks and themes using data-wp-* directives, @wordpress/interactivity stores, and server-side rendering. Use it when building interactive blocks, debugging directive behavior, or optimizing hydration and performance.
- Detect and integrate Interactivity API usage across blocks, themes, and plugins
- Set up server-side rendering with wp_interactivity_state() and wp_interactivity_data_wp_context()
- Implement and debug data-wp-* directives (data-wp-on--, data-wp-bind--, data-wp-context)
- Define derived state in PHP to prevent hydration mismatches and layout shifts
- Troubleshoot common failures: inert directives, hydration flicker, missing initial content, and performance regressions
- Support WordPress 6.9+ features including unique directive IDs and new TypeScript types
How to install wp-interactivity-api
npx skills add https://github.com/wordpress/agent-skills --skill wp-interactivity-api- WordPress 6.9+ (PHP 7.2.24+)
- Node.js and bash for filesystem-based workflows
- WP-CLI for some workflows
- wp-project-triage output to understand existing integration style
- @wordpress/scripts or compatible module bundler
How to use wp-interactivity-api
- 1.Run wp-project-triage to detect existing Interactivity API usage and integration style (block, theme, or plugin)
- 2.Identify the store definitions and confirm state shape, actions, and event handlers
- 3.Enable server directive processing by adding supports.interactivity in block.json or calling wp_interactivity_process_directives()
- 4.Initialize global state with wp_interactivity_state() and local context with wp_interactivity_data_wp_context() in PHP
- 5.Define derived state in PHP using closures to ensure correct initial HTML rendering before JavaScript loads
- 6.Implement directives with minimal scope, keeping data attributes stable and aligned between server and client
- 7.Verify the viewScriptModule is enqueued and the DOM element has data-wp-interactive with matching store namespace
- 8.Test with manual smoke tests and Playwright E2E tests around interaction paths
Use cases
- Building a new interactive block with viewScriptModule and client-side state management
- Debugging why a data-wp-on--click directive isn't firing on a theme component
- Adding server-side rendering to an existing interactive component to prevent layout shift
- Migrating from deprecated data-wp-ignore to modern directive patterns in WordPress 6.9
- Optimizing performance by scoping interactivity to smaller subtrees instead of broad roots
- Block developers building interactive WordPress blocks
- Theme developers adding interactivity to theme components
- Plugin developers enhancing existing markup with client-side behavior
- WordPress engineers debugging Interactivity API integration issues
- Full-stack WordPress developers optimizing performance and hydration
wp-interactivity-api FAQ
Use the Interactivity API when you need reactive state management, server-side rendering, and seamless hydration in WordPress blocks or themes. It handles directive processing, store management, and client-side navigation automatically. Use custom JavaScript only when the Interactivity API doesn't fit your use case.
Define derived state (like state.hasItems) in PHP using wp_interactivity_state() with closures, and ensure server-rendered HTML includes the correct initial attributes (e.g., hidden). This way, directives like data-wp-bind--hidden render correctly on first load before JavaScript takes over.
data-wp-ignore is now deprecated and will be removed. Use unique directive IDs with the --- separator instead (e.g., data-wp-on--click---plugin-a). New TypeScript types AsyncAction<ReturnType> and TypeYield<T> help with async action typing. getServerState() and getServerContext() now reset between page transitions.
Check: (1) the viewScriptModule is enqueued and loaded, (2) the DOM element has data-wp-interactive, (3) the store namespace in the directive matches the store definition, (4) there are no JavaScript errors before hydration. See references/debugging.md for detailed troubleshooting.
Yes, if you're creating a new interactive block from scratch. The official scaffold template provides best-practice setup for viewScriptModule, store integration, and server-side rendering. Use this skill to debug or enhance existing blocks.
Full instructions (SKILL.md)
Source of truth, from wordpress/agent-skills.
name: wp-interactivity-api description: "Use when building or debugging WordPress Interactivity API features (data-wp-* directives, @wordpress/interactivity store/state/actions, block viewScriptModule integration, wp_interactivity_*()) including performance, hydration, and directive behavior." compatibility: "Targets WordPress 6.9+ (PHP 7.2.24+). Filesystem-based agent with bash + node. Some workflows require WP-CLI."
WP Interactivity API
When to use
Use this skill when the user mentions:
- Interactivity API,
@wordpress/interactivity, data-wp-interactive,data-wp-on--*,data-wp-bind--*,data-wp-context,- block
viewScriptModule/ module-based view scripts, - hydration issues or “directives don’t fire”.
Inputs required
- Repo root + triage output (
wp-project-triage). - Which block/theme/plugin surfaces are affected (frontend, editor, both).
- Any constraints: WP version, whether modules are supported in the build.
Procedure
1) Detect existing usage + integration style
Search for:
data-wp-interactive@wordpress/interactivityviewScriptModule
Decide:
- Is this a block providing interactivity via
block.jsonview script module? - Is this theme-level interactivity?
- Is this plugin-side “enhance existing markup” usage?
If you’re creating a new interactive block (not just debugging), prefer the official scaffold template:
@wordpress/create-block-interactive-template(via@wordpress/create-block)
2) Identify the store(s)
Locate store definitions and confirm:
- state shape,
- actions (mutations),
- callbacks/event handlers used by
data-wp-on--*.
3) Server-side rendering (best practice)
Pre-render HTML on the server before outputting to ensure:
- Correct initial state in the HTML before JavaScript loads (no layout shift).
- SEO benefits and faster perceived load time.
- Seamless hydration when the client-side JavaScript takes over.
Enable server directive processing
For components using block.json, add supports.interactivity:
{
"supports": {
"interactivity": true
}
}
For themes/plugins without block.json, use wp_interactivity_process_directives() to process directives.
Initialize state/context in PHP
Use wp_interactivity_state() to define initial global state:
wp_interactivity_state( 'myPlugin', array(
'items' => array( 'Apple', 'Banana', 'Cherry' ),
'hasItems' => true,
));
For local context, use wp_interactivity_data_wp_context():
<?php
$context = array( 'isOpen' => false );
?>
<div <?php echo wp_interactivity_data_wp_context( $context ); ?>>
...
</div>
Define derived state in PHP
When derived state affects initial HTML rendering, replicate the logic in PHP:
wp_interactivity_state( 'myPlugin', array(
'items' => array( 'Apple', 'Banana' ),
'hasItems' => function() {
$state = wp_interactivity_state();
return count( $state['items'] ) > 0;
}
));
This ensures directives like data-wp-bind--hidden="!state.hasItems" render correctly on first load.
For detailed examples and patterns, see references/server-side-rendering.md.
4) Implement or change directives safely
When touching markup directives:
- keep directive usage minimal and scoped,
- prefer stable data attributes that map clearly to store state,
- ensure server-rendered markup + client hydration align.
WordPress 6.9 changes:
data-wp-ignoreis deprecated and will be removed in future versions. It broke context inheritance and caused issues with client-side navigation. Avoid using it.- Unique directive IDs: Multiple directives of the same type can now exist on one element using the
---separator (e.g.,data-wp-on--click---plugin-a="..."anddata-wp-on--click---plugin-b="..."). - New TypeScript types:
AsyncAction<ReturnType>andTypeYield<T>help with async action typing.
For quick directive reminders, see references/directives-quickref.md.
5) Build/tooling alignment
Verify the repo supports the required module build path:
- if it uses
@wordpress/scripts, prefer its conventions. - if it uses custom bundling, confirm module output is supported.
6) Debug common failure modes
If “nothing happens” on interaction:
- confirm the
viewScriptModuleis enqueued/loaded, - confirm the DOM element has
data-wp-interactive, - confirm the store namespace matches the directive’s value,
- confirm there are no JS errors before hydration.
See references/debugging.md.
Verification
wp-project-triageindicatessignals.usesInteractivityApi: trueafter your change (if applicable).- Manual smoke test: directive triggers and state updates as expected.
- If tests exist: add/extend Playwright E2E around the interaction path.
Failure modes / debugging
- Directives present but inert:
- view script not loading, wrong module entrypoint, or missing
data-wp-interactive.
- view script not loading, wrong module entrypoint, or missing
- Hydration mismatch / flicker:
- server markup differs from client expectations; simplify or align initial state.
- derived state not defined in PHP: use
wp_interactivity_state()with closures.
- Initial content missing or wrong:
supports.interactivitynot set inblock.json(for blocks).wp_interactivity_process_directives()not called (for themes/plugins).- state/context not initialized in PHP before render.
- Layout shift on load:
- derived state like
state.hasItemsmissing on server, causinghiddenattribute to be absent.
- derived state like
- Performance regressions:
- overly broad interactive roots; scope interactivity to smaller subtrees.
- Client-side navigation issues (WordPress 6.9):
getServerState()andgetServerContext()now reset between page transitions—ensure your code doesn't assume stale values persist.- Router regions now support
attachTofor rendering overlays (modals, pop-ups) dynamically.
Escalation
- If repo build constraints are unclear, ask: "Is this using
@wordpress/scriptsor a custom bundler (webpack/vite)?" - Consult:
references/server-side-rendering.mdreferences/directives-quickref.mdreferences/debugging.md
Related skills
More from wordpress/agent-skills and the wider catalog.

wp-performance
Diagnose and optimize WordPress performance using WP-CLI profiling, Query Monitor, and targeted fixes.

wp-phpstan
Configure and fix PHPStan static analysis in WordPress projects with proper typing and baseline management.

wp-playground
Spin up fast, disposable WordPress instances locally or in-browser for testing, debugging, and CI workflows.

wp-plugin-development
Develop WordPress plugins with architecture, hooks, security, and release guidance.

wp-plugin-directory-guidelines
Use when reviewing WordPress plugins for GPL compliance, checking license headers or compatibility, evaluating upsell/freemium/trialware patterns, validating plugin naming or trademark rules, checking plugin slugs, understanding why a plugin was rejected from WordPress.org, or answering any question about the 18 WordPress.org Plugin Directory guidelines — even if the user doesn't mention 'guidelines' explicitly.

wp-project-triage
Deterministic inspection of WordPress repositories with structured JSON reports for workflow guidance.