WordPress Interactivity API: Building Dynamic Components Without External Frameworks
Build interactive WordPress blocks with the native Interactivity API. Complete tutorial with accordion example, performance metrics, and practical implementation guidance.
WordPress developers building interactive blocks have traditionally faced a fragmented landscape—different plugins using React, Vue, jQuery, or custom solutions, often conflicting with each other. The Interactivity API, introduced in WordPress 6.5 (April 2024), provides a standardized, native approach to frontend interactivity that eliminates framework dependencies while offering significant performance advantages.
This tutorial covers the practical implementation of the Interactivity API, from basic setup through a complete working example.
What the Interactivity API Solves
Before this API, adding interactivity to WordPress blocks meant choosing between heavyweight frameworks or writing custom JavaScript that didn’t integrate well with WordPress’s PHP-first architecture. The Interactivity API addresses this by providing:
- Native PHP integration with WordPress hooks and filters
- Built-in server-side rendering for SEO and initial page load
- Lightweight runtime (~10KB compared to 30-100KB+ for React)
- Declarative syntax using HTML data attributes
Core WordPress blocks including Image (lightbox), Search, Query Loop, Navigation, and File already use this API.
Getting Started
The Interactivity API requires WordPress 6.5 or later. To scaffold a new interactive block:
npx @wordpress/create-block@latest my-interactive-block --template @wordpress/create-block-interactive-template
For existing blocks, enable the API in block.json:
{
"supports": {
"interactivity": true
},
"viewScriptModule": "file:./view.js"
}
The viewScriptModule property (note: Module, not Script) registers your JavaScript as an ES module, enabling the Interactivity API runtime.
Core Concepts
Directives
The API uses HTML data attributes called directives to bind behavior to elements. Key directives include:
| Directive | Purpose |
|---|---|
wp-interactive | Activates the API on an element and its children |
wp-context | Provides local state to an element subtree |
wp-bind | Dynamically sets HTML attributes |
wp-class | Toggles CSS classes based on state |
wp-text | Updates element text content reactively |
wp-on | Attaches event handlers |
State and Actions
State holds your data; actions modify it. When state changes, the UI updates automatically:
import { store } from '@wordpress/interactivity';
store( 'myblock', {
state: {
count: 0
},
actions: {
increment() {
const context = getContext();
context.count++;
}
}
});
Practical Example: FAQ Accordion
Here’s a complete accordion block demonstrating state management, event handling, and CSS class toggling.
PHP (render.php)
<?php
$context = array( 'isOpen' => false );
?>
<div
<?php echo get_block_wrapper_attributes(); ?>
data-wp-interactive="faq-accordion"
<?php echo wp_interactivity_data_wp_context( $context ); ?>
>
<button
class="faq-accordion__trigger"
data-wp-on--click="actions.toggle"
data-wp-bind--aria-expanded="context.isOpen"
aria-controls="faq-content"
>
<span class="faq-accordion__title"><?php echo esc_html( $attributes['question'] ); ?></span>
<span
class="faq-accordion__icon"
data-wp-class--is-open="context.isOpen"
></span>
</button>
<div
id="faq-content"
class="faq-accordion__content"
data-wp-class--is-visible="context.isOpen"
data-wp-bind--hidden="!context.isOpen"
>
<?php echo wp_kses_post( $content ); ?>
</div>
</div>
JavaScript (view.js)
import { store, getContext } from '@wordpress/interactivity';
store( 'faq-accordion', {
actions: {
toggle() {
const context = getContext();
context.isOpen = !context.isOpen;
}
}
});
Key Implementation Details
Server-rendered initial state: The wp_interactivity_data_wp_context() function outputs the initial state as a data attribute, ensuring content is visible before JavaScript loads.
Accessibility built-in: The wp-bind--aria-expanded directive automatically updates ARIA attributes as state changes.
Scoped state: Each accordion instance maintains its own isOpen state through context, so multiple accordions work independently.
No build step required: This example works without compilation. For JSX support, run npm run build with the standard WordPress scripts package.
Performance Benefits
The Interactivity API’s architecture provides measurable advantages:
Smaller JavaScript payload: The ~10KB runtime is shared across all interactive blocks. Compare this to React’s 30-100KB+ base requirement, plus additional code for each component.
No hydration mismatch: Since directives enhance server-rendered HTML rather than replacing it, there’s no flash of unstyled content or layout shift during JavaScript initialization.
Progressive enhancement: Content renders immediately from PHP. JavaScript adds interactivity after loading, but the page remains functional without it.
Single runtime: Multiple blocks using the Interactivity API share one runtime instance, unlike bundled frameworks where each plugin might include its own copy.
When to Use the Interactivity API
Ideal use cases:
- Interactive UI elements (accordions, tabs, toggles)
- Dynamic filtering and sorting
- Load more / infinite scroll
- Form validation and feedback
- Any block needing reactive state management
Consider alternatives when:
- Building complex single-page applications
- Your team has deep React expertise and existing React components
- You need advanced state management patterns (Redux-like stores)
For most WordPress block interactions, the Interactivity API provides the right balance of capability and simplicity without external dependencies.
Moving Forward
The Interactivity API represents WordPress’s commitment to a standardized frontend development approach. As more core blocks adopt it and the ecosystem matures, expect improved tooling and patterns.
Start with simple interactive elements—toggles, accordions, and dynamic UI states. The API’s declarative approach and PHP integration make it accessible to WordPress developers who prefer working with templates over JavaScript frameworks.
For complete documentation, see the WordPress Developer Resources.