I had a client the other day who was obsessed with a “word-flipping” effect they saw on some high-end SaaS homepage. You know the one—a heading that says “We make [Software, Apps, Magic]” and cycles through the words with a slick animation. They asked if they needed to move their whole site to a page builder just to get that one feature. I almost laughed. Of course not. But my first instinct was actually a mistake: I thought about building a custom block.
And that was the trap. If I built a custom block, the client would have to delete their existing headings and paragraphs and migrate everything into my new “Word Swapper” block. That’s a UX nightmare for the editor. The pragmatic way—the senior way—is to extend the Interactivity API core blocks experience. We want to take what’s already there and just add a bit of magic on top.
The Right Way to Extend Core Blocks
To pull this off without making a mess, we need to lean on a few modern WordPress APIs. First, we use the Format API to add a button to the rich-text toolbar. This lets the editor just highlight a list of comma-separated words and tag them. No custom blocks, no weird sidebars. Just native editing. This builds on the excellent foundation laid out in the Interactivity API guide on the Developer Blog.
Here’s the kicker: I initially tried to process the HTML using a simple regex replace in a PHP filter. Total disaster. It started breaking on nested spans and complex attributes. Trust me on this: use the WP_HTML_Tag_Processor. It’s the only way to safely inject attributes into core blocks without breaking the layout.
add_filter( 'render_block_core/paragraph', 'bbioon_word_switcher_render', 10, 2 );
function bbioon_word_switcher_render( $block_content, $block ) {
if ( strpos( $block_content, 'class="word-switcher"' ) === false ) {
return $block_content;
}
$processor = new WP_HTML_Tag_Processor( $block_content );
// Find our tagged span and inject Interactivity directives
while ( $processor->next_tag( [ 'tag_name' => 'span', 'class_name' => 'word-switcher' ] ) ) {
$processor->set_attribute( 'data-wp-text', 'state.currentWord' );
$processor->set_attribute( 'data-wp-class--fade', 'context.isFading' );
}
return $processor->get_updated_html();
}
Why the Interactivity API Wins
Once the HTML API has done its job on the server, the Interactivity API takes over in the browser. Instead of writing 100 lines of messy jQuery to find elements and manually toggle classes, we just define a “store.” The store handles the timing and the state. When the state changes, the UI updates automatically. It’s declarative, clean, and—most importantly—it doesn’t conflict with other plugins.
By using Script Modules (another native feature), we ensure this JavaScript only loads when it’s actually needed. This keeps the site fast. No one wants to load a 50kb animation library for a 2kb effect. That’s the difference between a dev who just “gets it done” and one who builds for the long haul.
So, What’s the Point?
- Don’t reinvent the wheel: Extend core blocks instead of building custom ones whenever possible.
- Use the HTML API: Stop using regex for HTML manipulation. Just stop.
- Declarative is better: The Interactivity API makes complex frontend states manageable.
Look, this stuff gets complicated fast when you start scaling. If you’re tired of debugging someone else’s mess and just want your site to work with modern standards, drop my team a line. We’ve probably seen it before.
Leave a Reply