Broadcast Channel API: Cross-Tab Communication in WordPress

The Broadcast Channel API lets multiple browser tabs or windows on the same origin exchange messages without a server round-trip. In WordPress this is useful for syncing cart state, invalidating admin caches, or showing a “logged out” warning across all open tabs when a session expires.

Problem: A WordPress admin page opens multiple browser tabs — for example, a split-screen comparison or a background processing tab — and needs to synchronise state (a completed import, a settings change) between tabs without polling a server endpoint.

Solution: Use the BroadcastChannel API to post messages between same-origin tabs. Create a channel with the same name in each tab, post a message with channel.postMessage(), and listen with channel.onmessage to react instantly when another tab reports a state change.

The examples below open a broadcast channel in a WordPress front-end script, post a cart-update message from the WooCommerce store, and receive it in the admin dashboard tab to update a live counter.

// cart-channel.js  — enqueued on every front-end page
const cartChannel = new BroadcastChannel( 'woo_cart' );

// Post a message whenever the cart changes (hook into WooCommerce's jQuery events)
document.addEventListener( 'wc_cart_hash_updated', () => {
    cartChannel.postMessage( {
        type: 'CART_UPDATED',
        count: parseInt( document.querySelector( '.cart-count' )?.textContent ?? '0', 10 ),
        timestamp: Date.now(),
    } );
} );

// admin-bar.js — also enqueued on front-end (or admin-bar on back-end pages)
const cartListener = new BroadcastChannel( 'woo_cart' );
cartListener.addEventListener( 'message', ( e ) => {
    if ( e.data?.type === 'CART_UPDATED' ) {
        const badge = document.querySelector( '#wp-admin-bar-my-account .cart-badge' );
        if ( badge ) badge.textContent = e.data.count;
    }
} );

// Always close the channel when the page unloads to avoid memory leaks
window.addEventListener( 'beforeunload', () => {
    cartChannel.close();
    cartListener.close();
} );

Use a broadcast channel to force re-login across all tabs when a WordPress session expires:

// session-monitor.js
const sessionChannel = new BroadcastChannel( 'wp_session' );

// On every authenticated REST request, check the response status
async function apiFetch( url, options = {} ) {
    const response = await fetch( url, options );
    if ( response.status === 401 ) {
        // Broadcast to all other tabs
        sessionChannel.postMessage( { type: 'SESSION_EXPIRED' } );
        handleSessionExpired();
    }
    return response;
}

// All tabs listen for session expiry
sessionChannel.addEventListener( 'message', ( e ) => {
    if ( e.data?.type === 'SESSION_EXPIRED' ) {
        handleSessionExpired();
    }
} );

function handleSessionExpired() {
    sessionChannel.close();
    // Show a non-dismissible overlay
    document.body.insertAdjacentHTML( 'beforeend',
        '

Your session has expired. Log in again

' ); }

NOTE: Broadcast Channel only works between same-origin contexts (same protocol, host, and port). For cross-origin communication use postMessage with explicit origin checks, or a SharedWorker if you need persistent state.

Leave Comment

Your email address will not be published. Required fields are marked *