v144 · privacy · demo

BroadcastChannel Pattern

Shared Storage’s cross-tab coordination use case maps cleanly onto BroadcastChannel + localStorage: both are standards-track, both are available today, and neither requires a Privacy Sandbox dependency. Open this page in multiple tabs to see real-time sync, a tab counter, and a shared state viewer.

Shared Storage is removed in Chrome 144. Open this page in two or more browser tabs — each tab announces itself via BroadcastChannel and the tab count updates live. Messages and localStorage changes propagate within ~10ms.
BroadcastChannel: checking… localStorage: checking… sharedStorage: checking… channel: showcase-bc-demo

tab counter

live count of tabs with this page open. Uses BroadcastChannel heartbeat.

1

tabs open

this tab

unique ID assigned to this tab on load.

known peers:

none yet

message composer

broadcast a message to all other open tabs.

message bus (blue = sent by this tab, green = received from peer):

no messages yet…

localStorage shared state:

keyvalue

the replacement pattern

// Shared Storage (removed) cross-tab pattern:
// sharedStorage.set("tab-count", n);  // ← gone in Chrome 144

// BroadcastChannel + localStorage replacement:
const BC_CHANNEL = "my-app";
const bc = new BroadcastChannel(BC_CHANNEL);

// --- Tab counter via heartbeat ---
const TAB_ID = crypto.randomUUID();
const peers  = new Map(); // id → lastSeen timestamp

bc.addEventListener("message", ({ data }) => {
  if (data.type === "announce") peers.set(data.tabId, Date.now());
  if (data.type === "bye")      peers.delete(data.tabId);
  updateTabCountUI(peers.size + 1);
});

// Announce on load, leave on unload
bc.postMessage({ type: "announce", tabId: TAB_ID });
addEventListener("pagehide", () => bc.postMessage({ type: "bye", tabId: TAB_ID }));

// --- Shared state ---
function setShared(key, value) {
  localStorage.setItem(key, JSON.stringify(value));
  bc.postMessage({ type: "state-changed", key, value });
}

see also