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.
Add this skill
npx mdskills install WordPress/wp-interactivity-apiComprehensive guide for WordPress Interactivity API with server-side rendering best practices and clear debugging workflow
1---2name: wp-interactivity-api3description: "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."4compatibility: "Targets WordPress 6.9+ (PHP 7.2.24+). Filesystem-based agent with bash + node. Some workflows require WP-CLI."5---67# WP Interactivity API89## When to use1011Use this skill when the user mentions:1213- Interactivity API, `@wordpress/interactivity`,14- `data-wp-interactive`, `data-wp-on--*`, `data-wp-bind--*`, `data-wp-context`,15- block `viewScriptModule` / module-based view scripts,16- hydration issues or “directives don’t fire”.1718## Inputs required1920- Repo root + triage output (`wp-project-triage`).21- Which block/theme/plugin surfaces are affected (frontend, editor, both).22- Any constraints: WP version, whether modules are supported in the build.2324## Procedure2526### 1) Detect existing usage + integration style2728Search for:2930- `data-wp-interactive`31- `@wordpress/interactivity`32- `viewScriptModule`3334Decide:3536- Is this a block providing interactivity via `block.json` view script module?37- Is this theme-level interactivity?38- Is this plugin-side “enhance existing markup” usage?3940If you’re creating a new interactive block (not just debugging), prefer the official scaffold template:4142- `@wordpress/create-block-interactive-template` (via `@wordpress/create-block`)4344### 2) Identify the store(s)4546Locate store definitions and confirm:4748- state shape,49- actions (mutations),50- callbacks/event handlers used by `data-wp-on--*`.5152### 3) Server-side rendering (best practice)5354**Pre-render HTML on the server** before outputting to ensure:5556- Correct initial state in the HTML before JavaScript loads (no layout shift).57- SEO benefits and faster perceived load time.58- Seamless hydration when the client-side JavaScript takes over.5960#### Enable server directive processing6162For components using `block.json`, add `supports.interactivity`:6364```json65{66 "supports": {67 "interactivity": true68 }69}70```7172For themes/plugins without `block.json`, use `wp_interactivity_process_directives()` to process directives.7374#### Initialize state/context in PHP7576Use `wp_interactivity_state()` to define initial global state:7778```php79wp_interactivity_state( 'myPlugin', array(80 'items' => array( 'Apple', 'Banana', 'Cherry' ),81 'hasItems' => true,82));83```8485For local context, use `wp_interactivity_data_wp_context()`:8687```php88<?php89$context = array( 'isOpen' => false );90?>91<div <?php echo wp_interactivity_data_wp_context( $context ); ?>>92 ...93</div>94```9596#### Define derived state in PHP9798When derived state affects initial HTML rendering, replicate the logic in PHP:99100```php101wp_interactivity_state( 'myPlugin', array(102 'items' => array( 'Apple', 'Banana' ),103 'hasItems' => function() {104 $state = wp_interactivity_state();105 return count( $state['items'] ) > 0;106 }107));108```109110This ensures directives like `data-wp-bind--hidden="!state.hasItems"` render correctly on first load.111112For detailed examples and patterns, see `references/server-side-rendering.md`.113114### 4) Implement or change directives safely115116When touching markup directives:117118- keep directive usage minimal and scoped,119- prefer stable data attributes that map clearly to store state,120- ensure server-rendered markup + client hydration align.121122**WordPress 6.9 changes:**123124- **`data-wp-ignore` is deprecated** and will be removed in future versions. It broke context inheritance and caused issues with client-side navigation. Avoid using it.125- **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="..."` and `data-wp-on--click---plugin-b="..."`).126- **New TypeScript types**: `AsyncAction<ReturnType>` and `TypeYield<T>` help with async action typing.127128For quick directive reminders, see `references/directives-quickref.md`.129130### 5) Build/tooling alignment131132Verify the repo supports the required module build path:133134- if it uses `@wordpress/scripts`, prefer its conventions.135- if it uses custom bundling, confirm module output is supported.136137### 6) Debug common failure modes138139If “nothing happens” on interaction:140141- confirm the `viewScriptModule` is enqueued/loaded,142- confirm the DOM element has `data-wp-interactive`,143- confirm the store namespace matches the directive’s value,144- confirm there are no JS errors before hydration.145146See `references/debugging.md`.147148## Verification149150- `wp-project-triage` indicates `signals.usesInteractivityApi: true` after your change (if applicable).151- Manual smoke test: directive triggers and state updates as expected.152- If tests exist: add/extend Playwright E2E around the interaction path.153154## Failure modes / debugging155156- Directives present but inert:157 - view script not loading, wrong module entrypoint, or missing `data-wp-interactive`.158- Hydration mismatch / flicker:159 - server markup differs from client expectations; simplify or align initial state.160 - derived state not defined in PHP: use `wp_interactivity_state()` with closures.161- Initial content missing or wrong:162 - `supports.interactivity` not set in `block.json` (for blocks).163 - `wp_interactivity_process_directives()` not called (for themes/plugins).164 - state/context not initialized in PHP before render.165- Layout shift on load:166 - derived state like `state.hasItems` missing on server, causing `hidden` attribute to be absent.167- Performance regressions:168 - overly broad interactive roots; scope interactivity to smaller subtrees.169- Client-side navigation issues (WordPress 6.9):170 - `getServerState()` and `getServerContext()` now reset between page transitions—ensure your code doesn't assume stale values persist.171 - Router regions now support `attachTo` for rendering overlays (modals, pop-ups) dynamically.172173## Escalation174175- If repo build constraints are unclear, ask: "Is this using `@wordpress/scripts` or a custom bundler (webpack/vite)?"176- Consult:177 - `references/server-side-rendering.md`178 - `references/directives-quickref.md`179 - `references/debugging.md`180
Full transparency — inspect the skill content before installing.