• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » How to build custom FSE Block Themes extensions utilizing modern Heartbeat API schemas

How to build custom FSE Block Themes extensions utilizing modern Heartbeat API schemas

Leveraging the Heartbeat API for Advanced FSE Block Theme Extensions

The WordPress Heartbeat API, often perceived as a mechanism for real-time data synchronization, offers a powerful, albeit underutilized, avenue for extending Full Site Editing (FSE) block themes. By understanding its underlying architecture and modern schema, developers can craft sophisticated, dynamic functionalities that go beyond static theme options. This post delves into building custom extensions for FSE block themes by strategically employing the Heartbeat API, focusing on practical implementation with PHP and JavaScript.

Understanding the Heartbeat API’s Role in FSE

The Heartbeat API facilitates frequent, non-intrusive communication between the browser and the server. In the context of FSE, this translates to opportunities for:

  • Real-time preview updates for dynamic theme elements.
  • Synchronizing custom editor controls with theme settings.
  • Implementing background tasks triggered by user activity within the editor.
  • Fetching and displaying dynamic data within block previews.

Registering Custom Heartbeat Routes

To extend the Heartbeat API’s capabilities for your FSE theme, you need to register custom routes. This is achieved using the heartbeat_routes filter in PHP. These routes will act as endpoints for your JavaScript to send and receive data.

PHP Implementation for Route Registration

Create a PHP file within your theme’s functions directory (e.g., inc/heartbeat-extensions.php) and include it in your functions.php. The following code demonstrates how to register a new route named my_fse_theme_data.

<?php
/**
 * Register custom Heartbeat API routes for FSE theme extensions.
 */
function my_fse_theme_register_heartbeat_routes( $routes ) {
    $routes['my_fse_theme_data'] = 'my_fse_theme_handle_heartbeat_data';
    return $routes;
}
add_filter( 'heartbeat_routes', 'my_fse_theme_register_heartbeat_routes' );

/**
 * Handle Heartbeat API data for custom FSE theme extensions.
 *
 * @param array $response The Heartbeat API response.
 * @param array $data     The data sent from the client.
 * @return array Modified response.
 */
function my_fse_theme_handle_heartbeat_data( $response, $data ) {
    // Process incoming data if any
    if ( isset( $data['my_custom_setting'] ) ) {
        // Sanitize and save the setting, e.g., using update_option()
        // For demonstration, we'll just echo it back.
        $response['my_custom_setting_received'] = sanitize_text_field( $data['my_custom_setting'] );
    }

    // Add custom data to the response
    $response['current_time'] = current_time( 'mysql' );
    $response['site_title']   = get_bloginfo( 'name' );

    return $response;
}
?>

In this example:

  • my_fse_theme_register_heartbeat_routes registers a new route my_fse_theme_data, which will be handled by the my_fse_theme_handle_heartbeat_data function.
  • my_fse_theme_handle_heartbeat_data receives the Heartbeat data. It can process incoming data (e.g., saving a custom theme setting) and adds its own data to the response (e.g., current server time and site title).

Client-Side JavaScript for Heartbeat Communication

On the client-side, you’ll enqueue a JavaScript file that utilizes the wp.heartbeat API. This script will send data to your registered route and process the response.

Enqueuing the JavaScript File

Add the following to your theme’s functions.php to enqueue your custom JavaScript file, ensuring it loads within the block editor.

<?php
/**
 * Enqueue custom Heartbeat API JavaScript for the block editor.
 */
function my_fse_theme_enqueue_heartbeat_script() {
    // Only load in the block editor.
    if ( ! is_admin() && ! wp_is_block_editor() ) {
        return;
    }

    wp_enqueue_script(
        'my-fse-theme-heartbeat',
        get_template_directory_uri() . '/js/heartbeat-extensions.js', // Path to your JS file
        array( 'wp-heartbeat' ),
        filemtime( get_template_directory() . '/js/heartbeat-extensions.js' ),
        true // Load in footer
    );
}
add_action( 'enqueue_block_editor_assets', 'my_fse_theme_enqueue_heartbeat_script' );
?>

JavaScript Implementation

Create a js/heartbeat-extensions.js file in your theme’s root directory. This script will interact with the Heartbeat API.

( function( window, document, wp, $ ) {
    'use strict';

    // Ensure wp.heartbeat is available
    if ( ! wp || ! wp.heartbeat ) {
        console.error( 'wp.heartbeat is not available.' );
        return;
    }

    // Define the heartbeat interval (in milliseconds)
    // WordPress default is 60000ms (60 seconds). Adjust as needed.
    // Be mindful of server load and user experience.
    var heartbeatInterval = 30000; // 30 seconds

    // Initialize Heartbeat
    wp.heartbeat.connect( {
        interval: heartbeatInterval
    } );

    // Handle Heartbeat events
    $( document ).on( 'heartbeat-send', function( e, data ) {
        // Add custom data to be sent to the server
        data.my_custom_setting = 'some_value_from_editor'; // Example: sending a value
        data.action = 'my_fse_theme_data'; // Crucial: matches the registered PHP route key
    } );

    $( document ).on( 'heartbeat-tick', function( e, data ) {
        // Process data received from the server
        if ( data.my_custom_setting_received ) {
            console.log( 'Server received custom setting:', data.my_custom_setting_received );
            // Example: Update a UI element in the editor based on server response
            // You might update a custom control's display or a status indicator.
        }

        if ( data.current_time ) {
            console.log( 'Server time:', data.current_time );
            // Example: Display server time in a custom editor panel
            // $( '#custom-server-time-display' ).text( data.current_time );
        }

        if ( data.site_title ) {
            console.log( 'Site Title:', data.site_title );
            // Example: Use site title in a custom block's preview
        }
    } );

    $( document ).on( 'heartbeat-connection-lost', function() {
        console.warn( 'Heartbeat connection lost.' );
        // Implement fallback or notification logic here
    } );

    $( document ).on( 'heartbeat-connection-restored', function() {
        console.log( 'Heartbeat connection restored.' );
        // Re-initialize or re-sync if necessary
    } );

} )( window, document, wp, jQuery );

Key points in the JavaScript:

  • wp.heartbeat.connect() initiates the Heartbeat connection. The interval parameter controls how often the client sends data.
  • The heartbeat-send event is triggered before data is sent. You add your custom data and importantly, the action key, which must match the route key registered in PHP (my_fse_theme_data).
  • The heartbeat-tick event fires when data is received from the server. You process the data object, which contains both your custom response data and any data added by WordPress core or other plugins.
  • heartbeat-connection-lost and heartbeat-connection-restored provide hooks for managing connection states.

Practical FSE Extension Examples

1. Dynamic Block Preview Updates

Imagine a custom block that displays the site’s current visitor count, which is updated periodically on the server. The Heartbeat API can fetch this count and update the block’s preview in the editor.

Server-Side (PHP – Add to my_fse_theme_handle_heartbeat_data)

    // ... inside my_fse_theme_handle_heartbeat_data function ...

    // Fetch dynamic data (e.g., visitor count from a transient or database)
    $visitor_count = get_transient( 'my_fse_theme_visitor_count' );
    if ( false === $visitor_count ) {
        // Simulate fetching or calculating visitor count
        $visitor_count = rand( 100, 1000 );
        set_transient( 'my_fse_theme_visitor_count', $visitor_count, 60 * 5 ); // Cache for 5 minutes
    }
    $response['visitor_count'] = $visitor_count;

    // ... rest of the function ...

Client-Side (JavaScript – Add to heartbeat-extensions.js)

    // ... inside $( document ).on( 'heartbeat-tick', ... ) ...

    if ( data.visitor_count ) {
        console.log( 'Current visitor count:', data.visitor_count );
        // Assuming you have a way to target a specific block's preview or a custom UI element
        // This is a conceptual example; actual implementation depends on block structure.
        // For instance, if you have a custom block with an attribute 'visitorCountDisplay':
        // wp.data.dispatch( 'core/editor' ).updateBlockAttributes( blockClientId, { visitorCountDisplay: data.visitor_count } );
        // Or update a custom UI element:
        // $( '#visitor-count-indicator' ).text( data.visitor_count );
    }

    // ... rest of the tick handler ...

2. Synchronizing Custom Editor Controls

If you’ve added custom meta boxes or controls outside the standard block editor UI that affect theme appearance, Heartbeat can help synchronize their state. For instance, a custom color picker in a theme options page that needs to reflect in the editor’s global styles.

Server-Side (PHP – Add to my_fse_theme_handle_heartbeat_data)

    // ... inside my_fse_theme_handle_heartbeat_data function ...

    // Get a custom theme option saved via theme settings or customizer
    $primary_color = get_option( 'my_fse_theme_primary_color', '#0073aa' ); // Default WordPress blue
    $response['primary_color'] = $primary_color;

    // ... rest of the function ...

Client-Side (JavaScript – Add to heartbeat-extensions.js)

    // ... inside $( document ).on( 'heartbeat-tick', ... ) ...

    if ( data.primary_color ) {
        console.log( 'Primary color from server:', data.primary_color );
        // Update the editor's global styles or a custom UI element
        // Example: Dispatching an action to update global styles (requires more complex integration)
        // wp.data.dispatch( 'core/editor' ).updateEditorSettings( {
        //     colors: {
        //         primary: data.primary_color
        //     }
        // } );
        // Or update a custom UI element:
        // $( '#primary-color-preview' ).css( 'background-color', data.primary_color );
    }

    // ... rest of the tick handler ...

Optimizing Heartbeat Usage

While powerful, the Heartbeat API can increase server load if not used judiciously. Consider these optimizations:

  • Adjust the Interval: Use the shortest interval necessary. For non-critical updates, a longer interval (e.g., 60-120 seconds) is preferable.
  • Conditional Data Sending: In the heartbeat-send event, only include data that is actually needed for the current context or tick.
  • Debounce/Throttle: If your JavaScript logic involves rapid updates or user interactions, consider debouncing or throttling your Heartbeat send events to avoid overwhelming the server.
  • Server-Side Logic: Keep server-side processing as efficient as possible. Cache data where appropriate.
  • Targeted Enqueuing: Ensure your Heartbeat script only loads in contexts where it’s needed (e.g., the block editor, specific admin pages).
  • Heartbeat Settings API: For more granular control over Heartbeat intervals and disabling it on specific pages, explore the heartbeat_settings filter in PHP.

Controlling Heartbeat Intervals and Disabling

You can control the Heartbeat interval globally or on a per-page basis using the heartbeat_settings filter. This is crucial for performance tuning.

<?php
/**
 * Control Heartbeat API settings.
 */
function my_fse_theme_heartbeat_settings( $settings ) {
    // Example: Increase the default interval to 90 seconds globally
    $settings['interval'] = 90000; // 90 seconds

    // Example: Disable Heartbeat on specific admin pages if not needed
    // global $pagenow;
    // if ( 'edit.php' === $pagenow ) { // Example: Disable on post edit screen
    //     $settings['disabled'] = true;
    // }

    // You can also control specific actions
    // $settings['php'] = array(
    //     'my_fse_theme_data' => array( 'interval' => 30000 ), // Shorter interval for our custom action
    // );

    return $settings;
}
add_filter( 'heartbeat_settings', 'my_fse_theme_heartbeat_settings' );
?>

By carefully managing these settings, you can balance the dynamic capabilities offered by the Heartbeat API with the need for a performant and stable WordPress environment.

Conclusion

The Heartbeat API, when integrated thoughtfully, provides a robust framework for building advanced, dynamic extensions for FSE block themes. By mastering the registration of custom routes and implementing intelligent client-side JavaScript, developers can create richer editing experiences, real-time previews, and more responsive theme functionalities. Always prioritize performance by tuning Heartbeat intervals and minimizing unnecessary data transfer.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Troubleshooting WP_DEBUG notice floods in production when using modern Elementor custom widgets wrappers
  • How to build custom Understrap styling structures extensions utilizing modern WordPress Options API schemas
  • How to build custom Genesis child themes extensions utilizing modern Heartbeat API schemas
  • Step-by-Step Guide to building a custom XML sitemap generator block for Gutenberg using Vanilla CSS shadow DOM style layers
  • WordPress Development Recipe: Secure token-based API authentication for Zapier dynamic webhooks in custom plugins

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (634)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (836)
  • PHP (5)
  • PHP Development (34)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (609)
  • SEO & Growth (492)
  • Server (23)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (218)
  • WordPress Theme Development (357)

Recent Posts

  • Troubleshooting WP_DEBUG notice floods in production when using modern Elementor custom widgets wrappers
  • How to build custom Understrap styling structures extensions utilizing modern WordPress Options API schemas
  • How to build custom Genesis child themes extensions utilizing modern Heartbeat API schemas

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (836)
  • Debugging & Troubleshooting (634)
  • Security & Compliance (609)
  • SEO & Growth (492)
  • Business & Monetization (390)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala