DEV Community

Cover image for Super simple communication between tabs, windows or iframes
Simon Ström
Simon Ström

Posted on • Edited on

Super simple communication between tabs, windows or iframes

At the time of writing this is not supported in Safari browsers. This code example uses this polifill, it offers partial support.

So, you have your web app running. The user opens it multiple times, in tabs or windows, or you might have several iframes on the same page, like the example below. Now you want to send data, events, or any other information across them. How do you do? Well, the answer is actually really simple...

Enter BrodacastChannel

All you have to create is a BroadcastChannel instance:

const channel = new BroadcastChannel('test')
Enter fullscreen mode Exit fullscreen mode

It only needs one parameter, the name of the channel. So in any other web app or piece of code you can create a connection by creating a new channel with the same name.

Note that the applications must be under the same origin. For example the same domain name, scheme (HTTP/HTTPS), and port.

Now you need to do two things:

  1. Subscribe to messages
  2. Send messages

So to subscribe, you need an event handler for the onmessage event:

channel.onmessage = e => {
  const { data } = e
  /* The code above is the same as:
   const data = e.data
   and uses a feature called object destructruring
  */
  console.log(data)
}
Enter fullscreen mode Exit fullscreen mode

The onmessage handler will receive the event payload, and the most interesting property would be the data sent. That is what is sent from another tab, frame, iframe, or window. Now look at how we send some data:

channel.postMessage('Hello!!!')
Enter fullscreen mode Exit fullscreen mode

Just use the postMessage function on your channel.

Now we send a simple string message to every other listener. Running the code above in one tab would look like this in another console: Hello!!!

The data you can send is not limited to strings. You can send objects as well.

To close a channel you can call the close method, so it stops listening and can be garbage collected:

channel.close()
Enter fullscreen mode Exit fullscreen mode

Below is a simple demo where you can change the background gradient in both iframes by clicking any button in either one of them:


Reuse the channel

If you want to reuse the channel you might do it by sending actions across like you handle actions using a reducer/redux. Example:


channel.onmessage = e => {
  const { data } = e

  switch(e.action) {
    case "ACTION_1":
      doActionOne(e.payload)
      return
    /* etc. */
  }
}

Enter fullscreen mode Exit fullscreen mode

And dispatching like this

channel.postMessage({
  type: "ACTION_1",
  payload: 42
})
Enter fullscreen mode Exit fullscreen mode

Summary

This is a really simple way to handle events across your application instances or different applications under the same domain. It might be session-/user information or any other data you want to broadcast. One day it might be working across all browsers without polyfill as well...

More information can be found here in the MDN docs

Cover photo by erica steeves on Unspash

Top comments (2)

Collapse
 
stroemdev profile image
Simon Ström

Well, depending on the use case the postMessage of window might be better. Since that is supported across browsers and you can work across origins. The real benefit of this is that you do not need access to the window object, for example running when running your application in multiple windows. The easiest way to demo was through iframes though.

This type of events that should be broadcasted might be a bit rare, could be regarding a session so you can log out of every instance at once. Or something like a dark theme toggle you can change all windows at once, but when using several iframes on the same page and you need to communicate they might be more coupled around one specific task, and should only communicate between each other. Not to any iframes on a diffrent tab or window. (Sorry for the long answer)

Collapse
 
kayrag profile image
Kayra Güneş

Nice :)