DEV Community

Chris Naismith
Chris Naismith

Posted on

Cross Tab Communication with Javascript

About a month ago an interesting problem came up at work, how can I listen to a form being submitted that may be in another tab? It's something that if it was in the same tab, would be much more straight forward. But I also wanted to know can I send messages between these two, or more, tabs.

What is Cross Tab Communication?

Cross Tab Communication is the ability of multiple tabs, windows, frames of iframes (further known as an instance) to send and receive 'messages' to and from other instances.

Limitations / Gotchas

This does come with some drawbacks. This will only work with domains on the same-origin.

You will not be able to use this across HTTP and HTTPS.
You will not be able to use this across different hosts.
You will not be able to use this across different ports.

How is this useful?

Before getting into some demos, I figure I would go over why this can be useful. Sometimes your users are going to have multiple instances of your site open, and how we handle their experience can be quite important.

For example, Dan Abramov's blog https://overreacted.io/ has a toggle for a dark mode/light mode. Using this, you could switch all open instances to the preferred theme without refreshing.

Examples / Demos

Example 1 - LocalStorage

External link if you don't want the preview


How this works is by setting/modifying a value in local storage or session storage on load of the application. When this happens, an event is fired that can be listened to on any other instance. This event contains information such as the key that was modified, the previous value, the new value and much more. If you're familiar with React, this is similar to how you can compare the previous props, to the current props in class lifecycle method componentDidUpdate.

Drawbacks of Example 1

There are some draw backs to using this method. For one, you can not store objects in local storage/session storage unless they are stringified. This means you would have to parse any of these values which may not be a huge deal, but in my opinion is not ideal.

The second draw back is that the event will not be fired if a value is updated to the same value. In my example I get around that limitation to setting the key loaded to Date.now().

Example 2 - BroadcastChannel

External link if you don't want the preview


In this example, I'm using the BroadcastChannel API. To do this, you create a new BroadcastChannel using a name (Similar to an IRC channel).

After subscribing to the channel you are returned an instance of the BroadcastChannel object, which in this example we use two parts of. You can send a message using the postMessage function, or attach a function to the onmessage property.

Similar with Example 1, and messages you send in one instance will be received in other instances. Along with the ability to subscribe to the same channel multiple times.

Drawbacks/Benefits of Example 2

Unlike Example 1, you are able to post full objects, arrays and other pieces of data.

However, Example 2 is a little bit more complicated and may be overkill depending on what you're trying to do.

Support for the BroadcastChannel API is also limited. Compared to local storage (globally at 92%), BroadcastChannel is at almost 76%. Chrome and Firefox both support it, with no support from IE, Safari and Edge. (Chromium Edge does support it, but is still considered in Beta as of this post).

More Usecases

This could be used in a CMS to let the user know they already have an instance open when trying to modify something, or to keep it in sync across tabs.

Authentication/locked content could be unlocked when logging in so that other windows are not out of sync.

Changing a profile picture

Communication between iframes.

Changing themes of a website, and syncing those changes across all tabs.

Conclusion

I don't think that this is going to be ground breaking and change the way we make our applications. But I do think implementing this across some features of our applications could improve the user experience.

If you have any other use cases you think this would be useful for, I'd love to hear it!

Resources

CanIUse - Localstorage
CanIUse - BroadcastChannel
MDN - BroadcastChannel

Top comments (9)

Collapse
 
vince_tblt profile image
Vincent Thibault

Some other possibilities :

  • SessionStorage (same than localStorage but w/o persistence)
  • SharedWorker (oups, deprecated !)
  • ServiceWorker (postMessage and loop other all opened window instances to broadcast message).
  • If all tabs are attached because opened from the same source page (const child = window.open()), you can communicate using the instance and window.opener.
Collapse
 
mvasigh profile image
Mehdi Vasigh • Edited

SharedWorker is not deprecated, right? MDN says nothing about that. It's probably the most well-supported way of doing this although BroadcastChannel has much better DX.

Also the npm package broadcast-channel does this with fallbacks to non-native BroadcastChannel alternatives i.e. localStorage (for IE) and idb.

Collapse
 
vince_tblt profile image
Vincent Thibault

SharedWorker was flagged “removed” from WebKit spec and IE didn’t plan to implement it.
The main reason for the dismiss is the ServiceWorker API that appeared soon after and can handle all the SharedWorker API.

Thread Thread
 
mvasigh profile image
Mehdi Vasigh

Ah I see, TIL. Thanks!

Collapse
 
darrenvong profile image
Darren Vong • Edited

I learn something new again as usual - never knew BroadcastChannel is a thing until now!

It will be interesting to see better browser support for it. localStorage had been a pain to share objects, especially with Edge due to its aggressive caching when I had to work with a tab/window sync problem at my work recently!

Collapse
 
itsjzt profile image
Saurabh Sharma

Local storage event listeners are not supported everywhere but it still blows my mind when

You logout in one tab and get logged out automatically in other tabs.

Collapse
 
jcubic profile image
Jakub T. Jankiewicz

When I first learned about localStorage storage event I've created a JavaScript library for sending messages between tabs called Sysend.js, it also support cross-domain communication. The first implementation used LS then added BroadcastChannel if supported. To give you perpective the idea for the project was based on my StackOverflow question Sending notifications between instances of the page in the same browser that I've asked in 2014 (even before ES6 was standarized), and I think I was the first one that implemented library like this.

Collapse
 
mansooromrani profile image
Mansoor Omrani • Edited

I think another method would be server push notifications. In the first tab the client notifies the server that I submitted a form. The server then notifies the second tab.

Collapse
 
naismith profile image
Chris Naismith

A benefit of this is that you dont need a server to do this. But it breaks down if you start using multiple browsers, and I would imagine containers in firefox as well.

But certainly is an option!