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
2. Initialize thepackage.json
and set up TypeScript.
Enter the following commands in your terminal.
npm init -y
npm install typescript --save-dev
Configure TypeScript by adding the following to tsconfig.json
.
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"outDir": "./dist",
"strict": true,
"esModuleInterop": true
},
"include": ["src"]
}
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"]
}
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');
});
5. Updatepackage.json
Script to build your Extension.
"scripts": {
"build": "tsc && cp manifest.json dist/"
},
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.
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
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}, '*');
}
});
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 });
}
});
});
}
});
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>
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
Twitter: https://twitter.com/Bhaskar_Sawant_
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 .
Subscribe to my newsletter
Read articles from Bhaskar Sawant directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Bhaskar Sawant
Bhaskar Sawant
Hello, I'm Bhaskar Sawant, a skilled software engineer from India. I specialize in frontend development, with strong full-stack capabilities and proficiency in UI/UX design, creating seamless, high-quality applications.