Chrome extensions are everywhere. They change the whole chrome browsing and development experiences like using adblocker to block ads on any website or dark mode everywhere or website CSS inspector. Ever wondered how to build such extensions? Well, it is very easy to get started on building an extension.
We are going to build an extension that will save any web URL and store them in chrome storage.
Extensions are small software programs that customize the browsing experience. They enable users to modify Chrome functionality and behavior to individual needs or preferences. An extension should complete a single task like saving the web links or show unread emails. It can contain multiple components and a long-range of functionalities.
They are built on web technologies such as HTML
, JavaScript
, CSS
and the chrome APIs.
Let’s get started on building an extension.
Every extension has a JSON formatted manifest file called manifest.json, which acts as an entry point of extension.
It provides important information like extension version, user permissions, external resources. So, it is a registration file for everything we add in the extension like using a remote server file or using chrome storage.
Create a directory and add the manifest.json file in the root of it.
{
"name": "Article Saver",
"version": "1.0.0",
"description": "Extension to save your links or articles",
"manifest_version": 2
}
This is the basic configuration stating the name of extension, description, version, and manifest_version which will be 2 as described by chrome.
This basic manifest file can be added to chrome extensions in development mode by following 3 easy steps:
Create an HTML in the root of the directory and link a script file to it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Article Saver</title>
<style>
body {
min-width: 300px;
height: 200px;
}
button {
border: none;
width: 100px;
height: 30px;
background-color: rgb(1, 100, 139);
color: white;
margin-bottom: 10px;
}
section {
display: flex;
flex-direction: column;
align-items: flex-start;
}
a {
width: 100%;
text-overflow: ellipsis;
white-space: nowrap;
overflow-x: hidden;
color: rgb(1, 100, 139);
text-decoration: unset;
padding: 5px 0;
}
a:hover {
background-color: rgb(228, 228, 228);
}
</style>
</head>
<body>
<button id="link">Save link</button>
<section id="list"></section>
<script src="popup.js"></script>
</body>
</html>
Register this HTML in manifest.json. Here we need to use browser action. Browser action is a button that your extension adds to the browser’s toolbar. The button has an icon and optionally popup. Now we can listen to any click on it, that will eventually open popup.
{
...
"browser_action": {
"default_popup": "popup.html"
}
}
We can easily add our custom icon rather than default provided by chrome. So, there is are three places for an extension where we can add icons.
To add icons we need three sizes of icons 16*16, 48*48, and 128*128. Then references these icons in the manifest.
"browser_action": {
"default_popup": "popup.html",
"default_icon": {
"16": "icon1.png",
"48": "icon2.png",
"128": "icon3.png"
}
},
"icons": {
"16": "icon1.png",
"48": "icon2.png",
"128": "icon3.png"
},
To reflect the latest changes we don’t have to remove the extension and reload it again. We can directly reload the extension using the refresh icon on the extension home page.
Then click on our extension, a popup will show the UI containing a save button.
At this stage, this extension is not saving any link.
Next, we will add the logic to save links and store them in chrome storage.
document.getElementById("link").addEventListener("click", () => {
const linkContainer = document.getElementById("list");
const newLink = document.createElement('a');
newLink.href = "demo link";
linkContainer.appendChild(newLink);
});
In our extension, if we didn’t add HTML and then you click on our extension button we could listen to that click via browserAction API in background script.
Register background.js in the manifest.json:
{
...
"background": {
"scripts": ["background.js"]
},
}
Register content.js in the manifest.json:
{
...
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
]
}
Since popup script can run only in the context of our extension UI, background script can’t access the current page context, and the content script has limited API access. We need some kind of communication between these parts so that can use these script to make our extension which will save our articles and sync them.
In extension context, we can communicate between background.js, popup.js and content.js easily using runTime API.
We will use runtime.sendMessage
for sending message and runtime.onMessage
for listening of messages.
document.getElementById("link").addEventListener("click", () => {
const linkContainer = document.getElementById("list");
const newLink = document.createElement('a');
chrome.runtime.sendMessage({message: "get_url"});
chrome.runtime.onMessage.addListener((request) => {
if( request.message === "updated_url" ) {
newLink.setAttribute('href', request.url);
newLink.setAttribute('target', "_blank");
newLink.innerText = request.title;
}
}
);
newLink.href = "fetching...";
linkContainer.appendChild(newLink);
});
chrome.runtime.onMessage.addListener((request) => {
if (request.message === "get_url") {
// Send a message to the active tab
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
var activeTab = tabs[0];
if (activeTab) {
chrome.tabs.sendMessage(activeTab.id, { "message": "fetch_current_url" });
}
});
}
});
chrome.runtime.onMessage.addListener((request) => {
if (request.message === "fetch_current_url") {
const currentUrl = location.href;
const currentTitle = document.title;
chrome.runtime.sendMessage({ "message": "updated_url", "url": currentUrl, title: currentTitle });
}
}
);
If we click the extension icon popup will open. Now click on the save button will save the current web URL to our list.
Right now if we close the tab and want to use the extension on any other page we can’t see the last stored link and also if you close the extension links list goes away from UI.
For that, we will use storage to store and sync our data across chrome.
We can use Chrome Storage API to store, retrieve, and track changes to user data.
We will use storage.sync
to store and retrieve the data. It also provides us the automatically synced data feature in chrome. It is asynchronous i.e non-blocking and faster than localStorage API.
First, register storage permission in the manifest.json.
{
...
"permissions": ["storage"],
}
Note: All other permissions like access active tab or bookmark permission are declared in this array.
Below is the updated popup.js to get the last stored links and sync them in chrome.
document.getElementById("link").addEventListener("click", () => {
// get the list element and create anchor tag
const linkContainer = document.getElementById("list");
const newLink = document.createElement('a');
// send message to background.js
chrome.runtime.sendMessage({ message: "get_url" });
// listen for message from content.js
chrome.runtime.onMessage.addListener((request) => {
if (request.message === "updated_url") {
newLink.setAttribute('href', request.url);
newLink.setAttribute('target', "_blank");
newLink.innerText = request.title;
// get the existing url and push the new link in the array
chrome.storage.sync.get(['urlList'], function (result) {
let updatedUrlList;
const urlObject = { url: request.url, title: request.title };
if (result.urlList && result.urlList.length > 0) {
updatedUrlList = result.urlList.concat([urlObject]);
} else {
updatedUrlList = [urlObject];
}
// set the updated array in storage
chrome.storage.sync.set({ 'urlList': updatedUrlList });
});
}
}
);
newLink.href = "fetching...";
linkContainer.appendChild(newLink);
});
// get data from storage to display existing urls
chrome.storage.sync.get(['urlList'], function (result) {
const existingUrls = result.urlList;
if (existingUrls && existingUrls.length > 0) {
existingUrls.forEach(el => {
const linkContainer = document.getElementById("list");
const newLink = document.createElement('a');
newLink.setAttribute('href', el.url);
newLink.setAttribute('target', "_blank");
newLink.innerText = el.title;
linkContainer.appendChild(newLink);
});
}
});
Yeah! We have our working extension ready to save our important links and store them in chrome. By building this extension we have covered all the fundamentals of chrome extension.
Our final directory structure will look like this:
Make the zip of the root folder and head over to chrome developer console. If you visiting the first time it will ask for one time registration fee. After that, you can click on the “New Item” button and select your zip file or you can drag and drop too.
In 7 steps, we have built and published a chrome extension. You can find the whole code on GitHub.
For more on Chrome extensions, you can visit Chrome docs.
For more tech blogs and information do follow us on LinkedIn and Twitter.
Thanks for reading. Enjoy!
India
86P, 4th Floor, Sector 44, Gurugram, Haryana 122003Singapore
#21-02, Tower 2A, The Bayshore condo, Singapore 469974Canada
8 Hillcrest Avenue Toronto ON M2N 6Y6, CanadaUS
31 River CT, Jersey City, New JerseySubscribe to our newsletter
Our Services
Top Reads
India
86P, 4th Floor, Sector 44, Gurugram, Haryana 122003
Singapore
#21-02, Tower 2A, The Bayshore condo, Singapore 469974
Canada
8 Hillcrest Avenue Toronto ON M2N 6Y6, Canada
US
31 River CT, Jersey City, New Jersey
Contact us
info@primathon.in
+91-9205966678
Reviews