SyncHub is a lightweight JavaScript library that enables master-slave synchronization between browser tabs using BroadcastChannel and localStorage. It prevents excessive server requests and ensures data consistency across tabs.
- ✅ Master tab handles data fetching
- ✅ Slave tabs stay passive and react to updates
- ✅ Automatic master re-election if the active tab changes
- ✅ Supports periodic data fetching or manual updates
- ✅ Designed for e-commerce carts, notifications, and any shared browser state
npm i @digilabscz/sync-hub-js
Then:
import SyncHub from '@digilabscz/sync-hub-js';
SyncHub.init();
or (CommonJS)
const SyncHub = require('@digilabscz/sync-hub-js');
SyncHub.init();
<script src="https://unpkg.com/@digilabscz/sync-hub-js@latest/dist/sync-hub.min.js"></script>
or
<script src="https://cdn.jsdelivr.net/npm/@digilabscz/sync-hub-js@latest/dist/sync-hub.min.js"></script>
The library will automatically call init()
method and register as window.SyncHub
.
<div id="notifications-badge" style="padding:10px; background:orange;"></div>
<script>
// Initialize task for static data
let task = window.SyncHub.registerTask('notifications-badge')
.onUpdate((newState, prevState) => {
renderNotificationBadge(newState, prevState);
});
// Manually update the task (can be triggered by button or event)
task.update(5);
function renderNotificationBadge(newState, prevState) {
const node = document.querySelector('#notifications-badge');
if (window.SyncHub.isMaster()) {
node.classList.add('master');
} else {
node.classList.remove('master');
}
node.innerHTML = `<strong>${newState}</strong><sup>/${prevState !== undefined ? prevState : 0}</sup>`;
}
// Render initial state (if any)
renderNotificationBadge(task.getState());
</script>
<div id="notifications-badge" style="padding:10px; background:orange;"></div>
<script>
// Create a task that fetches data every 5 seconds (only master tab runs fetch)
let task = window.SyncHub.registerTask('notifications-badge')
.onInterval(async (task) => {
const response = await fetch('https://api.example.com/notifications-count', { cache: "no-store" });
const count = await response.text();
return parseInt(count);
}, 5000, true) // true = run immediately
.onUpdate((newState, prevState) => {
renderNotificationBadge(newState, prevState);
});
function renderNotificationBadge(newState, prevState) {
const node = document.querySelector('#notifications-badge');
if (window.SyncHub.isMaster()) {
node.classList.add('master');
} else {
node.classList.remove('master');
}
if (newState > 0) {
node.classList.add('active');
} else {
node.classList.remove('active');
}
node.innerHTML = `<strong>${newState}</strong><sup>/${prevState !== undefined ? prevState : 0}</sup>`;
}
// Render initial state (if any)
renderNotificationBadge(task.getState());
</script>
Method | Description |
---|---|
SyncHub.registerTask(taskName) | Register a new named task |
task.onInterval(callback, intervalMs, runImmediately = false) | Define a periodic action the master tab should execute |
task.onUpdate(callback) | React to data updates in all tabs |
task.update(newData) | Manually trigger a new update |
task.getState() | Get the last known state of the task |
SyncHub.isMaster() | Check if the current tab is master |