Reference
Compressed sheet for open / post / listen / close. Print-friendly.
const auth = new BroadcastChannel("auth");
// auth.name === "auth" (read-only; set only at construction)
// Same string = same bus (exact match). Different name = different bus.
const theme = new BroadcastChannel("theme");
Window and workers
([Exposed=(Window,Worker)] in the HTML Standard).
"myapp:auth").
auth.onmessage = (event) => {
// event.data — structured-clone copy of what was posted
// event.origin — origin of the poster
if (event.data?.type === "logout") showLoggedOut();
};
// or:
auth.addEventListener("message", (event) => { /* … */ });
auth.onmessageerror = (event) => {
// deserialize failed (rare for ordinary JSON-shaped payloads)
};
// Local work first if this tab must update too — sender is excluded.
doLogoutLocally();
auth.postMessage({ type: "logout" });
// Strings, numbers, plain objects, arrays, many built-ins OK.
// Functions / DOM nodes → DataCloneError (structured clone rules).
// No transfer list — unlike Worker.postMessage(msg, [transfer]).
Other BroadcastChannel objects that are eligible for
messaging, share the same storage key / origin partitioning, and have
the same channel name. The poster’s own channel is
removed from destinations
((HTML §9.5).
auth.close();
// auth.postMessage("x"); // throws InvalidStateError (closed flag)
// Spec: close when done so listeners don’t pin the object (apparent leak).
// Context teardown (tab/worker close) also ends participation.
// every tab / relevant worker
const ch = new BroadcastChannel("app-sync");
ch.onmessage = (e) => {
switch (e.data?.type) {
case "logout":
clearSessionUI();
break;
case "theme":
applyTheme(e.data.value);
break;
case "invalidate":
refetch(e.data.resource);
break;
}
};
function setTheme(value) {
applyTheme(value); // local — sender excluded
localStorage.setItem("theme", value); // durable truth if needed
ch.postMessage({ type: "theme", value });
}
// on page teardown / leave feature
// ch.close();
| Trap | Fix |
|---|---|
| UI only updates in other tabs | Run local handler; then postMessage |
Post after close() |
Throws InvalidStateError — don’t reuse closed
channels
|
| Typo in channel name | Silent non-delivery — names must match exactly |
| Huge binary payloads | Clone cost; no transfer — keep messages small; store bulk in IDB/OPFS |
| Cross-origin “same site” | Wrong tool — origin must match (partitioning applies) |