Multiple tabs in your app
David Israel
Posted on November 1, 2020
Update 2024 use tab-election.
We had some problems with multiple tabs that are pretty common:
- Writing to storage could collide or not get picked up
- Logout in one tab would not be noticed in the other
- Sync with the backend would be done independently by all
Being Uclusion we of course used a Uclusion Dialog to decide and the options were:
- broadcast-channel the NPM package
- Broadcast channel API
- Service worker communication
Pretty easy decision because in addition to using broadcast channel API when available the NPM package supported leader selection. That allowed us to set up a React context to let us know anywhere in the code whether our tab was leader or not - see code here.
We could also send messages to the other tabs telling them to refresh from IndexedDB like so
const myChannel = new BroadcastChannel(COMMENTS_CHANNEL);
return myChannel.postMessage('comments').then(() => myChannel.close())
.then(() => console.info('Update comment context sent.'));
Now the basic idea we followed was the leader syncs from the backend and stores in an IndexedDB namespace and all other tabs store their local edits in a differently named IndexedDB namespace. Its very unlikely more than one tab is doing local edits at a time and even if somehow they were the sync from the network is the eventual master.
Also very simple logout broadcasts a message which is listened for by the other tabs here
const [logoutChannel, setLogoutChannel] = useState(undefined);
useEffect(() => {
console.info('Setting up logout channel');
const myLogoutChannel = new BroadcastChannel('logout');
myLogoutChannel.onmessage = () => {
console.info('Logging out from message');
onSignOut().then(() => console.info('Done logging out'));
}
setLogoutChannel(myLogoutChannel);
return () => {};
}, []);
Posted on November 1, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 24, 2024
July 24, 2024
October 20, 2023