Super simple communication between tabs, windows or iframes

stroemdev

Simon Ström

Posted on February 8, 2021

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

💖 💪 🙅 🚩
stroemdev
Simon Ström

Posted on February 8, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related