Building an Open Source Chrome Extension from Scratch -- Part 1

Building an Open Source Chrome Extension from Scratch -- Part 1

What is a manifest ? What is a background file and service workers ? How does a popup work ?? All such questions will be answered here.

In this series , we will make a Chrome Extension from scratch which will tell us the number of tabs open in the browser.

Prerequisites

  • For this extension, you will need basic HTML

  • JavaScript DOM manipulation, callback functions.

We will be covering CSS, JS fetch and promises in the next articles.

This Chrome extension is made with the newer Manifest Version 3 as MV3 has better privacy, security, and performance . Google is also dropping support for MV2 soon but in case you want to learn more about MV3 , read here. You can request a MV2 version of the extension by reaching out to me on my socials.


Starting with the Basic Question....

What are Extensions?!?!!!!

Going by the book, i.e the Official Chrome Extension Documentation,

Extensions are small software programs that customize the browsing experience

These Extensions are built on web technologies such as HTML, JavaScript, and CSS and run in a separate, sandboxed execution environment and interact with the Chrome browser. Extensions allow you to

  • Automate functionality in your browser
  • Modify existing behaviors
  • Improve your browser experience

To create an extension, you assemble some resources -- a manifest, JavaScript and HTML files, images, and other things that constitute the extension -- so let's start building one.

The following will be the folder structure of the extension and is available on tabsMonster Github repo

--- tabsMonster-chrome
    |
    |--background.js
    |
    |--img
    |   |
    |   |
    |   tabsMonster-16.png
    |   tabsMonster-32.png
    |   ...
    |
    |--manifest.json
    |
    |--popup.html
    |
    |--popup.js
    |

Create the manifest

But before we write it out, what is a manifest??

manifest.json is a JSON-formatted file that provides important information about the extension. It is like the identification certificate of the Chrome Extension.

To get started , we will have the bare minimum and we will build upon it.

{
    "manifest_version": 3,
    "name": "tabsMonster",
    "description": "A Chrome extension to keep a tab on your Browser Tabs.",
    "version": "0.0.0"
}

After adding the the above in a manifest.json file in a directory named tabsMonster-chrome, we will have a Chrome extension ready to be loaded on the Browser.

  • Open Chrome Browser.

  • Go to Browser Options --> More Tools --> Extensions

  • Turn on the Developer Mode in the top right

  • Click Load Unpacked and select the tabsMonster-chrome directory.

image.png

You will see your extension in the tab and CONGRATULATIONS🎉🎉🎉, you just made a Chrome Extension.

But can it do anything yet?

spiderman-magic.gif

It was like writing 'Hello World' till now. Let us dive a little deeper.

Add functionality

A variety of functionalities can be added to a Chrome Extension but you have to decide what exactly you want to implement.

image.png

image.png

image.png

We will be using the above highlighted functionalities in this article out of the complete dev guide.

Register the background-script/service-worker in the manifest

{
    "manifest_version": 3,
    "name": "tabsMonster",
    "description": "A Chrome extension to keep a tab on your Browser Tabs.",
    "version": "0.0.0",

    // Registering background script
    "background": {
        "service_worker": "background.js"

    }

}

What exactly is a service worker and what can it do?

A service worker is a script that your browser runs in the background, separate from a web page, opening the door to features that don't need a web page or user interaction.

A background service worker is loaded when it is needed, and unloaded when it goes idle. Some examples of events include:

  • Extension install or update.
  • The background page was listening for an event, and the event is dispatched.
  • Message recieved through content script or popup.

Create the background script


//background.js

chrome.runtime.onInstalled.addListener(function(object) {
    chrome.tabs.create(
        { 
            url: "https://aunicorndev.github.io/tabsMonster/" 
        }
    );
});

What is chrome.x.y.z??

Chrome provides special-purpose APIs which reside under the chrome namespace and have different modules like runtime, tabs,action etc.(full list here) which can be used only by the extension's code to interact with the Browser. For in depth explanation, watch this video

These API's give access to browser properties, methods and events which can have callback functions in response to the event triggers.

In the above example,

An eventListener(chrome.runtime.onInstalled.addListener) is attached which will fire once the Chrome Extension is installed.

Once the event is fired, a callback function we will create a new tab (chrome.tabs.create) with the tabsMonster landing page as the URL.

Reloading the Extension

image.png Once the changes to manifest.json and background.js have been made, reload the extension and two things will happen.

  • A new tab will be created with the tabsMonster landing page

image.png

  • On opening Extensions tab, you will see a service worker file in your extension

image.png

Introduce a user interface

Jumping on to the main goal, we want to count the number of currently open tabs and display that count somewhere... So how do we do that ??

Thankfully Chrome Extension provides an interface which behaves like a small website in its own and can use the Chrome API's to get the data we require.

Add Permissions for Interface

{
    "manifest_version": 3,
    "name": "tabsMonster",
    "description": "A Chrome extension to keep a tab on your Browser Tabs.",
    "version": "0.0.0",
    "background": {
        "service_worker": "background.js"

    },

    // Icons for the extension
    "icons": { 
        "16":"./img/tabsMonster-16.png",
        "32":"./img/tabsMonster-32.png",
        "48":"./img/tabsMonster-48.png",
        "128": "./img/tabsMonster-128.png" 
    },

    // Action settings
    "action": {

        "default_icon": {
            "16":"./img/tabsMonster-16.png",
            "32":"./img/tabsMonster-32.png"
        },
        "default_popup": "popup.html"
    }


}

The icons have different function for different sizes as listed below

Icon SizeIcon Use
16x16favicon on the extension's pages
32x32Windows computers often require this size. Providing this option will prevent size distortion from shrinking the 48x48 option.
48x48displays on the extensions management page
128x128displays on installation and in the Chrome Webstore

image.png

Create the action and Layer Logic

<!--popup.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>tabsMonster</title>
</head>
<body>
    tabsMonster
    <h1 class="tabsCount"></h1>
   <!--Script tag for logic-->
    <script src="./popup.js"></script>
</body>
</html>

Here we simply add a boilerplate code with a <script src="./popup.js"></script> in the body and a h1 with a class= tabsCount which will be populated in the next step.

Logic for popup.js


//popup.js

const tabsCount = document.querySelector('.tabsCount');

const setMonsterData = (res)=>{

    tabsCount.textContent = res.monster;
}


document.addEventListener('DOMContentLoaded',()=>{

    chrome.tabs.query({windowType:'normal'}, function(tabs) {    
        setMonsterData({ monster:tabs.length })        
    })

})

This is where the functionality is introduced in the interface..

We get the tabs information in a callback function on querying the chrome.tabs API and use the tabs.length property to set the number of tabs in popup.html.

The changes in the background.js and manifest.json will only reflect when you reload the extension

After reloading and clicking on the extension in the extension list, you will be able to see the number of tabs open for your browser !!

image.png

And VOILÁ 🔥🔥, you have a working Chrome Extension in your browser !!

xCSs2rQ.gif

BUT WAIT

That is not all, in the next blogs in this series we will learn to use more Chrome API's like the storage,content scripts,options and add more functionalities to it by calling external API's.


Did you like this Open Source project and want to learn & contribute?? Jump in github.com/aUnicornDev/tabsMonster..

Give it a ⭐ while you are at it.. Really helps in motivating us 😊.

Thanks.png

Did you find this article valuable?

Support aUnicornDev's Blog by becoming a sponsor. Any amount is appreciated!