@react-lib-tech/tab-utils
v1.0.2
Published
Broadcast messages & run code only once across all browser tabs
Maintainers
Readme
Cross-Tab Communication & Single-Execution Logic
We use @react-lib-tech/tab-utils to enable cross-tab messaging and ensure certain logic runs only once across all open tabs.
Why?
- Sync logout, theme, and language changes across tabs
- Prevent duplicate API calls and background jobs
- Ensure session consistency for all users
Installation
npm install @react-lib-tech/tab-utilsUsage Example
import { BroadcastMessage, OnMessage, CallOnce } from "@react-lib-tech/tab-utils";
// Broadcast logout to all tabs
function logoutAllTabs() {
BroadcastMessage("LOGOUT", { reason: "manual" });
}
// Listen for logout in all tabs
useEffect(() => {
OnMessage("LOGOUT", () => {
window.location.href = "/login";
});
}, []);
// Run polling only in one tab
useEffect(() => {
CallOnce("start-polling", () => {
setInterval(() => {
// polling logic
}, 5000);
});
}, []);Common Events
LOGOUTTHEME_CHANGEDLANG_CHANGEDPROFILE_UPDATEDSESSION_RENEW
See the library documentation for more details.
Features
- 🔁 Broadcast messages between tabs
- 🧏 Listen for messages in all tabs (including the current one)
- 🔒 Run specific code only once, even if the user opens multiple tabs
- ❌ Prevent duplicate API calls / background tasks
- 🔄 Keep sessions, logout, theme, and language in sync across tabs
- ✅ SSR-safe (works with Next.js – no
windowerrors on server)
Why use this library?
In real apps, users usually open multiple tabs of the same app:
- “Dashboard” in one tab
- “Reports” in another tab
- “Profile” somewhere else
This causes typical issues:
- ❌ User logs out in one tab → other tabs still look “logged in”
- ❌ You start polling an API in each tab → your server is hammered
- ❌ You trigger an expensive job multiple times
- ❌ Theme / language changes only apply to one tab
- ❌ You don’t know which tab should be “primary”
@react-lib-tech/tab-utils fixes that:
- Only one tab can run a critical piece of code
- All tabs can listen & react when something happens in any tab
- Everything is done with
localStorage& the nativestorageevent - No backend, no WebSocket, no service worker required
API Reference
🧠 CallOnce(lockname, callback, timeout?)
Runs callback only once even across multiple tabs. Useful for heavy tasks, polling, or analytics.
🔁 BroadcastMessage(messageId, data)
Broadcasts a message to all tabs—including the current one.
📥 OnMessage(messageId, handler)
Listen & respond when a broadcast message is received.
Real-world examples
Logout everywhere
BroadcastMessage("LOGOUT", {});
OnMessage("LOGOUT", () => location.replace("/login"));Sync theme
BroadcastMessage("THEME_CHANGED", "dark");
OnMessage("THEME_CHANGED", applyTheme);One-tab-only polling
CallOnce("polling", startPolling);How it works
- Uses localStorage
- Triggers storage event in other tabs
- Manual callback in current tab
- Cleanup done automatically
- No WebSocket, no backend, no PWA setup required.
Browser Support
| Browser | Supported | | ------- | --------- | | Chrome | ✔ | | Firefox | ✔ | | Edge | ✔ | | Safari | ✔ |
SSR / Next.js
This library uses safe guards:
if (typeof window !== "undefined")So it does NOT break Next.js during SSR/hydration.
Troubleshooting
- Storage events not firing?
- Events trigger only across separate browser tabs — not inside a single tab.
- Why callback runs for current tab?
- We call it intentionally for convenience.
Best use cases
- Synced logout
- Synced theme/language
- Only one tab runs background tasks
- Distributed workload
- Preventing duplicate API calls
- Session consistency
