Building a Chrome Extension

Building a Chrome Extension

ยท

5 min read

I'll be frank: it proved to be less simple than my initial expectations. I encountered numerous inquiries during the construction process and had to acquire unfamiliar knowledge.

I aimed to formulate a set of instructions that could be effortlessly duplicated by anyone, even individuals lacking developer expertise, while crafting this extension or any similar one. Furthermore, I intended to convey the insights I gained following a session of collaborative programming with GitHub Copilot and human developers, which occurred after a night of work.

How to build a Chrome extension

To get started, youโ€™ll need to have an IDE. General steps for creating an extension from designing the folder structure to running the project locally in Chrome.

An example of a Chrome extension file structure.

For your convenience, here's a chart that succinctly outlines the purpose of these files:

  • manifest.json ๐Ÿงพ: This file contains metadata regarding your extension, encompassing details like its name, version, and permissions. "Manifest" functions as a proper noun representing the Google Chrome API, with the most recent iteration being V3.

  • popup.js ๐Ÿ–ผ๏ธ: Upon users clicking on your extension icon within the Chrome toolbar, a pop-up window emerges. This particular file dictates the behavior of the pop-up and includes code to manage user interactions with it.

popup.html and style.css ๐ŸŽจ: These two files collaboratively shape the visual presentation of your pop-up window. While popup.html deals with the interface's layout, structure, and content, style.css determines how the HTML content should be exhibited in the browser, encompassing elements like fonts, text colors, and backgrounds.

Generate the manifest.json

Within a directory in my integrated development environment (IDE), I established a file named manifest.json. Within the manifest.json file,

I defined the intended characteristics of my file:

Manifest outlining a Chrome extension designed to clear browser cache. manifest_version: 3 The extension's permissions include: storage, tabs, browsingData I pressed the "Enter" key and activated GitHub Copilot's suggestions by typing an opening curly brace. Subsequently, I removed the lines detailing my original manifest.json intentions, resulting in the following finalized file:

{
    "name": "Clear Cache",
    "version": "1.0",
    "manifest_version": 3,
    "description": "Clears browser cache",
    "permissions": [
        "storage",
        "tabs",
        "browsingData"
    ],
    "action": {
        "default_popup": "popup.html"
    },
    "background": {
        "service_worker": "background.js"
    }
 }

Create a service worker, which is a file called background.js

I acquired knowledge about its significance through a developer who joined my livestream ๐Ÿ‘ฅ. The background.js is the component responsible for enabling your extension to operate in the background, execute functions, and react to user actions beyond the extension's pop-up window. This encompasses tasks such as network requests and data storage.

๐Ÿง‘๐Ÿพโ€๐Ÿ’ป Within my background.js file, I included a comment outlining my intended service worker:

The final file looked like this:


// console.log when extension is installed
chrome.runtime.onInstalled.addListener(function() {
    console.log("Extension installed");
 });

 // send response when message is received and console.log when message is received
 chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    console.log("Message received");
    sendResponse("Message received");
 });

Create the popup.html file

๐Ÿง‘๐Ÿพโ€๐Ÿ’ป Inside the popup.html file, I inserted a comment delineating the desired visual presentation of my pop-up window. This particular window is what users will encounter upon clicking the extension icon.

<!DOCTYPE html>
<html>
   <head>
       <meta charset="utf-8">
       <title>Clear Cache</title>
       <link rel="stylesheet" href="style.css">
   </head>
   <body>
       <h1>Clear Cache</h1>
       <button id="allHistory">Entire History</button>
       <button id="pastMonth">Past Month</button>
       <button id="pastWeek">Past Week</button>
       <button id="pastDay">Past Day</button>
       <button id="pastHour">Past Hour</button>
       <button id="pastMinute">Past Minute</button>
       <p id="lastCleared"></p>
       <script src="popup.js"></script>
   </body>
</html>

Test the browser extension

Prior to integrating further styles or interactivity, I chose to assess the alterations. I lean towards implementing gradual adjustments and conducting manual evaluations intermittently due to its streamlining effect on the debugging phase.

๐Ÿง‘๐Ÿพโ€๐Ÿ’ป Open your Chrome browser and visit chrome://extensions. Activate developer mode, then select โ€œLoad unpacked.โ€ Import the folder containing your Chrome extension. Once loaded, you should be able to execute testing for your extension. Below is the appearance of mine:

Create a popup.js file to add interactivity

// convert date and time into human-readable format

function convertDate(date) {
    let date = new Date(date);
    var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
    return date.toLocaleDateString("en-US", options);
 }

 // add successfully cleared cache into paragraph with id "lastCleared"
 function addCleared() {
    var p = document.getElementById("lastCleared");
    let date = new Date();
    p.innerHTML = "Successfully cleared cache " + convertDate(date);
 }

 // clear all cache history
 document.getElementById("allHistory").addEventListener("click", function() {
    chrome.browsingData.removeCache({ "since": 0 }, function() {
        addCleared();
    });
 });

 // clear cache history from the past month
 document.getElementById("pastMonth").addEventListener("click", function() {
    let date = new Date();
    date.setMonth(date.getMonth() - 1);
    chrome.browsingData.removeCache({ "since": date.getTime() }, function() {
        addCleared();
    });
 });

 // clear cache history from the past week
 document.getElementById("pastWeek").addEventListener("click", function() {
    let date = new Date();
    date.setDate(date.getDate() - 7);
    chrome.browsingData.removeCache({ "since": date.getTime() }, function() {
        addCleared();
    });
 });

 // clear cache history from the past day
 document.getElementById("pastDay").addEventListener("click", function() {
    let date = new Date();
    date.setDate(date.getDate() - 1);
    chrome.browsingData.removeCache({ "since": date.getTime() }, function() {
        addCleared();
    });
 });

 // clear cache history from the past hour
 document.getElementById("pastHour").addEventListener("click", function() {
   let date = new Date();
    date.setHours(date.getHours() - 1);
    chrome.browsingData.removeCache({ "since": date.getTime() }, function() {
        addCleared();
    });
 });

 // clear cache history from the past minute
 document.getElementById("pastMinute").addEventListener("click", function() {
   let date = new Date();
    date.setMinutes(date.getMinutes() - 1);
    chrome.browsingData.removeCache({ "since": date.getTime() }, function() {
        addCleared();
    });
 });

Adding styles to it

body {
    background-color: #f7f7f7;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
    margin: 0;
}

h1 {
    font-size: 32px;
    color: #333;
    margin-bottom: 20px;
}

button {
    background-color: #4CAF50;
    color: white;
    padding: 12px 24px;
    font-size: 16px;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    margin: 6px;
    transition: background-color 0.3s ease-in-out;
}

button:hover {
    background-color: #45a049;
}

button:active {
    background-color: #3e8e41;
}

p {
    font-weight: bold;
    font-size: 18px;
    color: #333;
    margin-top: 20px;
}

Conclusion

In conclusion, embarking on the journey of developing this extension has been both enlightening and rewarding. Navigating through the intricacies of manifest files, scripting functionalities, and user interfaces has provided invaluable insights into the world of browser extensions. The process, though at times challenging, has underscored the importance of incremental changes and meticulous testing in ensuring a smooth and refined user experience.

You can check out my github repository.

ย