SkillAgentSearch skills...

Across Tabs

Easy communication between cross-origin browser tabs. Simplified "CORS"ing!

Install / Use

npx skills add wingify/across-tabs

Installs into whichever agent you are using.

README

<img src="https://raw.githubusercontent.com/wingify/across-tabs/master/across-tabs.png" alt="Across tabs" width="50" height="50"/> AcrossTabs - Easy communication between cross-origin browser tabs.

npm version npm Build Status Coverage Status

NPM

<a href="https://news.ycombinator.com/item?id=14041400"><img src="https://raw.githubusercontent.com/wingify/across-tabs/master/images/hn.png" width="150" height="20"/></a> <a href="https://www.producthunt.com/posts/across-tabs"><img src="https://raw.githubusercontent.com/wingify/across-tabs/master/images/product_hunt.png" width="100" height="20"/></a>

LIVE DEMO

Features

  1. Safely enables cross-origin communication among different browser tabs. Uses PostMessage API for communication.
  2. Easy to hook custom callback at various levels. Eg: executing a custom method in Child's tab on receiving a message from Parent tab.
  3. Option to provide data-tab-opener="name" attribute on the target link/button(which opens up a new tab), so that it remains to disable until Child tab initiates a handshake and is received by the Parent tab
  4. Fully fledged API to get information regarding the tabs(Parent and Child tabs) and other communication-related methods.
  5. Exports in a UMD format i.e. library works everywhere.
  6. Only ~4 KB gzipped.

Installation

  1. Via npm
$ npm install across-tabs
  1. Via bower
$ bower install across-tabs
  1. Via cdnjs, using <script> tag
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/across-tabs/1.0.0/across-tabs.min.js"></script>

Note: Use the desired version of the library in place of 1.0.0. Checkout cdnjs across-tabs.

Flow Diagram

  • Opener/Parent tab(P) opens up a new Child tab(C).
  • C initiates a handshake with the P tab by sending a postMessage.
  • P acknowledges the request and sends C it's identity i.e. UUID along with P information.
  • This sets up a communication channel between Parent and Child tab.
  • Now, P and C can share custom messages with each other.
  • Whenever C gets closed/refreshed, P is notified.
  • Whenever P is closed/refreshed, all children of P tab gets notified.
<img src="https://raw.githubusercontent.com/wingify/across-tabs/master/parent-tab-communication.jpg" />

Explanation of diagram

  • Parent(P) opens Child tab(C1) at t=1.
  • c1a - When C1 initiates a handshake with the Parent.
  • P1 - When P receives C1 message.
  • P2 - P acknowledges the request and sends the C1 its identity.
  • c1b - When C1 receives an acknowledgement message along with identity from P.

Total Tabs Associated: 1 | Opened Tabs: 1 | Closed Tabs: 0


  • Parent(P) opens CHild tab(C2) at t=10.
  • c2a - When C2 initiates a handshake with the Parent.
  • P3 - When P receives C2 message.
  • P4 - P acknowledges the request and sends the C2 its identity.
  • c2b - When C2 receives acknowledgemnet message along with identity from P.

Total Tabs Associated: 2 | Opened Tabs: 2 | Closed Tabs: 0


  • c1c - Tab C1 closes.
  • P5 - P is notified about the C1. Parent updates the list.

Total Tabs Associated: 2 | Opened Tabs: 1 | Closed Tabs: 1


  • Parent(P) opens CHild tab(C3) at t=25.
  • c3a - When C3 initiates a handshake with the Parent.
  • P6 - When P receives C3 message.
  • c2c - Tab C2 sends a custom message.
  • P7 - When P receives a message from tab C2. It processes it.
  • P8 - P acknowledges the request and sends the C3 its identity.
  • c3b - When C3 receives acknowledgemnet message along with identity from P.

Total Tabs Associated: 3 | Opened Tabs: 2 | Closed Tabs: 1


  • When Parent Tab P is closed, all the opened tabs are notified about it.

Usage

Create an instance / reference before using.

Opener(Parent) tab

var config = {
  onHandshakeCallback: function () { ... },
  onPollingCallback: function () { ... },
  onChildCommunication: function () { ... }
}
var parent = new AcrossTabs.Parent(config);

Constructor accepts a configurable Object with the following keys.

  • heartBeatInterval: The time interval for polling tabs statuses
  • removeClosedTabs: Pass it as true to have only opened tabs in the list
  • shouldInitImmediately: Pass it as false to create an instance but initialize it later
  • onHandshakeCallback: Callback to be called when a successful connection has been established
  • onChildCommunication: Callback to be called when child sends message
  • onPollingCallback: Callback to be called every time a tab is polled for its status
  • origin: whitelist origin for securing postMessage communication. It will discard the malicious messages trying to trick the behavior. Eg. http://example.com
  • parse: parser used when parsing messages, defaults to JSON.parse
  • stringify: stringifier used when converting data into messages, defaults to JSON.stringify

| Config Keys | default | accepts | | ------------------------- | -------------- | ---------------------------------- | | heartBeatInterval | 500 msec | A number representing milliseconds | | removeClosedTabs | false | Boolean | | shouldInitImmediately | true | Boolean | | onHandshakeCallback | Undefined | Function as callback | | onChildCommunication | Undefined | Function as callback | | onPollingCallback | Undefined | Function as callback | | origin | '*' | String(url) | | parse | JSON.parse | Function | | stringify | JSON.stringify | Function |

New(Child tab)

var config = {
  onReady: onReady,
  onInitialize: onInitialize,
  isSiteInsideFrame: false, // dont set if not required
  handshakeExpiryLimit: 4000, // msec
  onParentDisconnect: onParentDisconnect,
  onParentCommunication: onParentCommunication
};
var child =  new AcrossTabs.Child(config);

Constructor accepts a configurable Object with the following keys.

  • handshakeExpiryLimit: Time to wait for getting an acknowledgement from Parent window for child's request
  • onReady: Callback to be invoked once child instance is ready
  • onInitialize: Callback when a child instance is actually initiated
  • onParentDisconnect: Callback to be invoked when Parent gets disconnected
  • onParentCommunication: Callback to be invoked whenever Parent communicates with the child tab
  • isSiteInsideFrame: If the library is loaded inside an iframe in the child tab, this needs to be set true for maintaining proper window/frame(s) references
  • origin: whitelist origin for securing postMessage communication. It will discard the malicious messages trying to trick the behavior. Eg. http://example.com
  • parse: parser used when parsing messages, defaults to JSON.parse
  • stringify: stringifier used when converting data into messages, defaults to JSON.stringify

| Config Keys | default | accepts | | ------------------------- | -------------- | -------------------------------------- | | handshakeExpiryLimit | 5000 msec | A number representing milliseconds | | isSiteInsideFrame | null | If child tab has actual site in a fram | | onReady | Undefined | Function as callback | | onInitialize | Undefined | Function as callback | | onParentDisconnect | Undefined | Function as callback | | onParentCommunication | Undefined | Function as callback | | origin | '*' | String(url) | | parse | JSON.parse | Function | | stringify | JSON.stringify | Function |

Example is included in the example folder. Vanilla JS and Vue js versions are there to test out. Note: Run npm install if you wish to run vuejs example since the example needs the vue-js library to work.

API

Refer above section on how to create an instance before hitting API methods.

Opener Tab(Parent) Methods
  • openNewTab

    Saves `data

Related Skills

View on GitHub
GitHub Stars1.7k
CategoryDevelopment
Updated11d ago
Forks108

Languages

JavaScript

Security Score

100/100

Audited on Jul 28, 2026

No findings