How to build your Chrome Extension in 5 minutes

Devanshani Rasanjika
Aeturnum
Published in
7 min readJun 12, 2023

--

Chrome is a well-spread platform that can develop your own Chrome extensions. If you want to make Chrome extensions and are new to Chrome extensions this is the right article for you.

Chrome extension is a small piece of software that can run inside a Chrome browser. It can enhance Chrome functionalities and create a custom user experience and as well as can track the user’s browser activities. They are built using web technologies such as Javascript, HTML, and CSS and do not need any advanced technologies.

Chrome extensions run in an isolated manner which does not impact the browser functionality. So any fault in an extension does not bring down the browser process.

File structure

  • Manifest.json — Every extension requires a JSON-formatted file named manifest.json that provides important information which is the entry point for the Chrome extension. This file must be located in the extension’s root directory and called manifest.json. This is the configuration file for the extension and it will contain the owner’s name, version, and permissions that we need to allow to access the Chrome APIs, etc.
  • Service Worker — Run in the background of your browser & listen to every event that happening in the browser. So here we are going to call it background.js. For example, if you want to write a function such as any information saved to session storage this function should be written in the background script.
  • content scripts — Content scripts are run in the context of a web page and have access to the embedding web page DOM which can enhance the UX of the existing web page. So it can manipulate the DOM elements of the browser web page & it also can use the Chrome APIs.
  • popup.html — If you want to show an interface when clicking on the extension you can write the logic here.
  • popup.css — Do the styling for the HTML.
  • popup.js — Writing the logic for the HTML.

Important Chrome APIs

Here I will be going to discuss important Chrome APIs that we need to build a simple Chrome extension.

  • chrome. notifications — Create notifications & send the notifications to users in the system tray.
  • chrome. runtime — Listen to background.js, and communicate between the service worker & content script.
  • chrome.storage — Read & write to the website's local storage.
  • chrome.tabs — Interact with the browser tab system. For example can find the active tab, and modify and rearrange tabs in the browser.
  • chrome.cookies — Can query the session cookies from any web page, modify the cookies & identify cookies change events.

Communication between Service Worker & Content Script

Since Service workers run in the background of your browser and content scripts run in the context of the browser we need to have a specific mechanism to communicate between these scripts. Here we can use chrome.runtime API to send & receive messages.

Let’s get started!

First, we need to have the manifest.json configuration file which is the entry point for the Chrome extension as below. Here I will be going to develop the Chrome extension using Manifest version 3.

Create the Manifest.json:

{
"manifest_version": 3, // Manifest version
"name": "Demo extension", // Name of the Extension
"version": "0.0.1", //Version number of the Extension
"author": "Test", // Author (not mandatory)
"action": {
"default_popup": "popup.html", //Interface when you click on the extension
"default_icon": "get_started128.png",
"default_title": "Demo extension" //Show when you hover the Extension
},
"content_scripts": [
{
"matches": ["<all_urls>"],//if you target specific site to inject the Content Script you can put here
"js": ["contentscript.js"]//Script running in the browser console
}
],
"background": {
"service_worker": "background.js"//Script run in the background & listen to events happening in the browser
},
"permissions": ["tabs","activeTab","scripting","contextMenus"], //Allow specific permissions
"host_permissions": ["https://*/"] //Allow access to specific host
}

Content Script to Service Worker:

Here in the Content Script, I will be going to call the chrome.runtime.sendMessage API to handle the communication.

chrome.runtime.sendMessage(
{
message: "Hi message from content script",
},
(response) => {
console.log(response.message);
}
);

And in the Service Worker, there should be a callback function to receive the response from the Content Script as below.

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log(message);
sendResponse({ message: "Response from background js" });
});

Testing:

  • Once the manifest and other files are ready, head over to chrome://extensions in the browser.
  • Enable the developer’s mode.
  • Click the LOAD UNPACKED button and select the extension directory.
  • The extension has been successfully installed.

Next, Reload & open a new tab in the browser and inspect the developer tools. you can see the response message from the Service Worker hit in the browser web page console. At the same time click on the service worker inside the installed Chrome extension for debugging. In the service worker console, you can see the received message from the content script.

Service Worker to Content Script:

On the other way, we can send messages to the Content Script from the Service Worker to perform the tasks.

Here I’m going to show how to add a menu item when right-clicking on a browser web page & send a message to the Content Script to change the background color. So we need to include the contextMenus permission under the permissions in the manifest.json file as "permissions":["tabs","activeTab","scripting","contextMenus"] .

Next, the Service Worker needs to register a listener at the time of Chrome Extension installation to create a new context menu item as below.

chrome.runtime.onInstalled.addListener(function () {
chrome.contextMenus.create({
id: "changeBgColor",
title: "Change Background Color",
contexts: ["all"],
});
});

Once the menu item gets created should write the click event functionality to send a message to the Content Script to change the background color since the Content Script has the permission to change the DOM of the browser web page.

chrome.contextMenus.onClicked.addListener(function (info, tab) {
if (info.menuItemId == "changeBgColor") {
chrome.tabs.sendMessage(tab.id, { action: "changeBgColor", color: "red" });
}
});

And in the Content Script, there should be a listener to listen to the messages from the Service Worker and do the requested changes as below.

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.action == "changeBgColor") {
document.body.style.backgroundColor = request.color;
}
});

Next, reload the extension to apply the changes and check how the background color change when clicking on the new menu item.

Build a Simple Chrome Extension to check the Jenkins build status

Next, I will use the above-explained basics to build a simple Chrome extension that is able to check the Jenkins build status. So to check the Jenkins build status I set up the Jenkins server in the local environment which is running in the http://localhost:8080 . From the Jenkins [GET]http://localhost:8080/api/json?tree=jobs[name,color] API we can get all the build status in the API response. So next my goal is to integrate Jenkins API via the Chrome extension and upon clicking on the extension should show an interface with all the jobs with their status respectively.

Let’s get started!

  • Create the manifest.json file with the necessary permissions as below. Here we don't need Content Script since we are not going to change the DOM of browser web pages.
{
"manifest_version":3,
"name":"Jenkins build status checker",
"version": "0.0.1",
"description": "Check the status of Jenkins jobs",
"host_permissions":["http://localhost:8080/*"], //Allow access to Jenkins host URL
"background":{
"service_worker":"background.js"
},
"permissions":["storage","tabs","notifications"],
"action":{
"default_popup":"popup.html",
"default_icon": "icon.png",
"title": "Jenkins build status checker"
}
}
  • Create the Service Worker as background.js and here we need to call the Jenkins API in chrome.runtime.onInstalled & chrome.tabs.onUpdated listeners as below. After receiving the response from the Jenkins API I will be going to write the response to local storage using chrome.storage API.
chrome.runtime.onInstalled.addListener(() => {
callJenkinsApi();
});

callJenkinsApi = () => {
fetch("http://localhost:8080/api/json?tree=jobs[name,color]")
.then((response) => response.json())
.then((data) => {
console.log(data.jobs);
chrome.storage.sync.set({ jenkinsData: data.jobs });
});
};

chrome.tabs.onUpdated.addListener(function(id,changeInfo,tab){
callJenkinsApi();
})
  • Next, create an interface to show the Jenkins build status in a table view using popup.html.
<html>
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}

td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}

tr:nth-child(even) {
background-color: #dddddd;
}
</style>
<head>
<script src="popup.js"></script>
</head>
<body style="width: 400px;">
</body>
</html>
  • Next, I will be going to write the logic to create the table view using popup.js. Here API response will be read from the local storage using chrome.storage API & once the user checks the status of the jobs it will be notified in the system tray as successfully checked the Jenkins build status using chrome.notifications API as below.
chrome.notifications.create(`my-notification-${Date.now()}`, {
type: "basic",
iconUrl: "icon.png",
title: "Jenkins build status check",
message: "succesfully checked for all jobs",
});

function updatePopup() {
chrome.storage.sync.get(["jenkinsData"], function (data) {
var jobs = data.jenkinsData;
var table = document.createElement("table");
var th1 = document.createElement("th");
th1.innerHTML = "Job";
var th2 = document.createElement("th");
th2.innerHTML = "Status";
table.appendChild(th1);
table.appendChild(th2);
for (var i = 0; i < jobs.length; i++) {
var tr = document.createElement("tr");

var td1 = document.createElement("td");
var td2 = document.createElement("td");

var text1 = document.createTextNode(jobs[i].name);
var status = "not built";
if (jobs[i].color == "red") {
status = "Failed";
} else if (jobs[i].color == "blue") {
status = "Success";
}

var text2 = document.createTextNode(status);

td1.appendChild(text1);
td2.appendChild(text2);
tr.appendChild(td1);
tr.appendChild(td2);
table.appendChild(tr);
}
document.body.appendChild(table);
});
}
document.addEventListener("DOMContentLoaded", updatePopup);

Hopefully, this helps to understand the usage of background scripts, content scripts, and manifest.json files when you are building out your amazing new Chrome extension.

You can find the full source code for the Chrome Extension to check the Jenkins build status from here.

Thank you for reading!

Happy coding!

--

--