DEV Community

Cover image for How to transfer data between tabs using a Chrome extension
Bhaskar Sawant
Bhaskar Sawant

Posted on

How to transfer data between tabs using a Chrome extension

In today’s interconnected web, it’s common to need communication between different browser tabs, even if they come from different origins. Chrome extensions and the postMessage API make it easy to transfer data between tabs. You can create a Chrome extension using TypeScript to facilitate cross-origin communication. In this guide, I’ll show you how.

What You Will Learn

  • Setting up a basic Chrome extension with TypeScript.

  • Using postMessage API for cross-origin communication.

Setting up a basic Chrome extension with TypeScript.

First, let’s set up a basic Chrome extension project with TypeScript.

Follow these steps:

1. Create the Project Structure

I’ll be using this project structure throughout this project.

my-chrome-extension/
├── src/
   ├── background.ts
   ├── content.ts
├── manifest.json
├── tsconfig.json
└── package.json
Enter fullscreen mode Exit fullscreen mode

2. Initialize thepackage.jsonand set up TypeScript.

Enter the following commands in your terminal.

npm init -y
npm install typescript --save-dev
Enter fullscreen mode Exit fullscreen mode

Configure TypeScript by adding the following to tsconfig.json .

{
    "compilerOptions": {
      "target": "ES6",
      "module": "commonjs",
      "outDir": "./dist",
      "strict": true,
      "esModuleInterop": true
    },
    "include": ["src"]
}
Enter fullscreen mode Exit fullscreen mode

3. Configuremanifest.json.

Create a file named manifest.json and add the following to configure the manifest.

This is the configuration file of your Chrome Extension.

{
    "manifest_version": 3,
    "name": "My Chrome Extension",
    "version": "1.0",
    "background": {
      "service_worker": "background.js",
      "type": "module"
    },
    "content_scripts": [
      {
        "matches": ["<all_urls>"],
        "js": ["content.js"],
        "run_at": "document_start"
      }
    ],
    "permissions": ["tabs"]
}
Enter fullscreen mode Exit fullscreen mode

4. Create service_worker and content script.

Create src/background.ts in the folder structure, this will be the service worker of your Chrome Extension, it will keep running in the background.

Create src/content.ts in the folder structure, this will be the content script of your Chrome Extension, it gets loaded in every active tab in your browser. Add the following code to the content.ts .

document.addEventListener('DOMContentLoaded', () => {
    console.log('content.ts loaded');
});
Enter fullscreen mode Exit fullscreen mode

5. Updatepackage.jsonScript to build your Extension.

  "scripts": {
    "build": "tsc && cp manifest.json dist/"
  },
Enter fullscreen mode Exit fullscreen mode

Now enter npm run build in your terminal to build the Chrome Extension.

6. Load the Extension in Chrome.

  • Open Chrome and navigate to the Extensions page: Type chrome://extensions/ in the address bar and press Enter.

  • Enable Developer Mode: Toggle the switch on the top right to enable Developer Mode.

  • Load Unpacked Extension: Click on the “Load unpacked” button and select the dist folder of your project.

Your extension should be loaded, and the manifest, background script, and content script should be correctly set up.

To confirm open a tab, open the developer tools of your browser and click on the console tab, there you’ll see the console log which we wrote in the content.ts .

This way you can create a simple Chrome Extension.

Using postMessage API for cross-origin communication.

Now let us see how we can communicate between multiple tabs using postMessage API.

This tab inter-communication works not exactly but on a type of basic PubSub architecture in which background.ts which is our service worker works as a publisher and content.ts which our content script works as a subscriber.

When we send a message from one tab to the content script of that tab the content script forwards that message to the service worker and then the service worker forwards that message to the content script of all other active tabs.

Image description

Image description

Now, let’s code this up. 😄

1. Add Chrome types in the TypeScript project.

To use Chrome API in the TypeScript project we need to install the following package.

npm i @types/chrome
Enter fullscreen mode Exit fullscreen mode

2. Set up the Content Script.

The content script will listen for the messages from the tab and send them to the background script then the background script will forward the messages to the content scripts of all other active tabs and then the content script will forward the message received from the background script to the tab.

 //content.ts : 

document.addEventListener("DOMContentLoaded", () => {console.log("Hello from content script")});

//this will listen to the message from the tab and send it to the background script
window.addEventListener("message", (event) => {
  if (event.source !== window || !event.data.type) return;
  const {type, data} = event.data;
  if (type === "FROM_TAB") {
    chrome.runtime.sendMessage({ type: "FROM_TAB", data });
  }
});

//this will listen to the message from the background script and send it to the tab
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  const { type, data } = message;
  if (message.type === "TO_TAB") {
    console.log("content script sending message to tab", message.data);
    window.postMessage({type:'FROM_CONTENT', data}, '*');
  }
});
Enter fullscreen mode Exit fullscreen mode

3. Set up the background script (service worker).

//background.ts :
//this will listen to the message from the content script and send it to 
//the content scripts of all the active tabs
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  const {type, data} = message.data
    if (message.type === 'FROM_TAB') {
      chrome.tabs.query({}, (tabs) => {
        tabs.forEach(tab => {
          if (tab.id && tab.id !== sender.tab?.id) {
            chrome.tabs.sendMessage(tab.id, { type: 'TO_TAB', data  });
          }
        });
      });
    }
  });
Enter fullscreen mode Exit fullscreen mode

Now save all the files and enter npm run build in your terminal to build the Chrome Extension.

Now go to the Extensions tab and refresh your extension.

To test this out will create a simple HTML page.

<!-- index.-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>Waiting for messages:</h2><br />
    <p id="texts"></p>
</body>
<script>
    let texts = document.getElementById('texts');
    window.addEventListener('message', (event) => {
        const {type, data} = event.data;
        if (type === "FROM_CONTENT") {
            console.log(event.data);
            texts.innerHTML += data + '<br />';
        }
    });
</script>
</html>
Enter fullscreen mode Exit fullscreen mode

This will listen to all messages and print them on the screen. you can use plugins like Live Server to start this HTML file.

Let’s see this in action. 😄

By following this guide, you’ve learned how to set up a Chrome extension with TypeScript and enable seamless cross-origin communication between tabs using the postMessage API. This powerful setup allows for a richer, more interconnected user experience across different browser tabs. using postMessage API you can achieve things like scrapping, messaging and many more.

Follow Me for More Insights

If you found this guide helpful and want to learn more about web development, Software Engineering, and other exciting tech topics, follow me here on Medium. I regularly share tutorials, insights, and tips to help you become a better developer. Let’s connect and grow together in this journey of continuous learning!

Connect with Me

Stay tuned for more articles, and feel free to reach out if you have any questions or suggestions for future topics.

Cheers, thanks for reading! 😊

Happy coding! 🚀

This article was originally published on Medium. It is also available on Hashnode and Dev.to .

Top comments (0)