Multiple tabs in your app

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:

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 () => {};
  }, []);

David Israel
David Israel Co-Founder of Uclusion