notes

Log | Files | Refs | README

broadcastchannel_api.md (3320B)


      1 # Broadcast Channel API
      2 
      3 ```
      4 BroadcastChannel (cross-context bus)
      5 ---------------------------------------
      6 
      7      [ Tab 1 ]           [ Tab 2 ]             [ Worker / Tab 3 ]
      8    +-----------+       +-----------+           +-----------------+
      9    | App code  |       | App code  |           |  App code       |
     10    | publishes |       | subscribes|           |  subscribes     |
     11    +-----+-----+       +-----+-----+           +--------+--------+
     12          |                   |                         |
     13          +---------+---------+-------------------------+
     14                    v
     15           +-----------------------+
     16           |  BroadcastChannel     |   browser-level bus
     17           |  ("app-events")       |
     18           +-----------------------+
     19 ```
     20 
     21 `BroadcastChannel` is a built-in browser API that lets different browser
     22 contexts (tabs, iframes, workers) on the same origin communicate by posting
     23 messages to a named channel. It's essentially a pub/sub bus at the browser level
     24 — perfect for syncing state across tabs without a server.
     25 
     26 ## Typed BroadcastChannel in TypeScript
     27 
     28 You can wrap it in a typed class to get full compile-time safety:
     29 
     30 ```ts
     31 type StateMessage<T> =
     32   | { type: "STATE_UPDATE"; payload: Partial<T> }
     33   | { type: "REQUEST_SYNC" };
     34 
     35 class SyncedStore<T extends object> {
     36   private state: T;
     37   private channel: BroadcastChannel;
     38   private subscribers = new Set<(s: T) => void>();
     39 
     40   constructor(name: string, initial: T) {
     41     this.state = { ...initial };
     42     this.channel = new BroadcastChannel(name);
     43     this.channel.onmessage = (e: MessageEvent<StateMessage<T>>) => {
     44       if (e.data.type === "STATE_UPDATE") {
     45         this.state = { ...this.state, ...e.data.payload };
     46         this.subscribers.forEach((cb) => cb(this.state));
     47       }
     48     };
     49   }
     50 
     51   setState(updates: Partial<T>) {
     52     this.state = { ...this.state, ...updates };
     53     this.channel.postMessage({ type: "STATE_UPDATE", payload: updates });
     54     this.subscribers.forEach((cb) => cb(this.state));
     55   }
     56 
     57   subscribe(cb: (s: T) => void) {
     58     this.subscribers.add(cb);
     59     return () => this.subscribers.delete(cb);
     60   }
     61 
     62   destroy() {
     63     this.channel.close();
     64   }
     65 }
     66 ```
     67 
     68 TypeScript's MessageEvent<T> generic ensures the e.data payload is typed
     69 correctly, preventing you from accidentally posting or reading the wrong shape. ​
     70 
     71 ### Common Use Cases
     72 
     73 - Session sync — if a user logs out in one tab, broadcast a logout action to
     74   immediately reflect that across all open tabs ​
     75 
     76 - Shopping cart sync — changes made in one tab propagate instantly to others
     77 
     78 - Shared worker state — coordinate state between a ServiceWorker and page tabs
     79 
     80 ### Limitations to Know
     81 
     82 - BroadcastChannel does not fire in the tab that sent the message — only other
     83   tabs receive it, so you still update local state directly ​
     84 
     85 - It only works within the same origin (same protocol + domain + port)
     86 
     87 - It has no built-in message history — a newly opened tab won't get past state
     88   unless you implement a REQUEST_SYNC handshake pattern (one tab requests the
     89   current state, another responds with it)
     90 
     91 - Not available in IE, but has full support in all modern browsers
     92 
     93 This pattern pairs naturally with the observable store from the previous answer
     94 — the BroadcastChannel becomes an external subscriber that mirrors state updates
     95 to other tabs.