This article was originally published on this site

Browser extensions can be a great way to put your coding skills to good use and build something that will allow you to do repetitive tasks with just a few clicks. If you want to achieve that, learning how to write a Chrome extension is a great start.
Google Chrome provides many different APIs to its extension developers, such as adding a new page, pop-up, creating notifications, setting up a default search engine, or even creating a context menu item (the menu that shows up when you right-click on a page).
The possibilities are limitless, from an extension that renders “Hello World!” to an extension that allows you to take a screenshot of the web page.

How to write a Chrome extensionHow to write a Chrome extension

📚 Table of contents:

In this tutorial, we will show you how to write a Chrome extension that sends browser notifications from a popup menu. We will also use the context menu and data storage APIs to make the most out of it. We are calling it Notify! with an exclamation mark!
Create a Google Chrome ExtensionCreate a Google Chrome Extension
📥 The extension’s code is public on GitHub so feel free to fork and use it.

How to write a Chrome extension: the structure
Before we move ahead, you should look at Google Chrome’s developer documentation to learn about Chrome extension development in general.
Also, if you are looking to write a Chrome extension for the Chrome Web Store, please look at their single-purpose policy.
Let’s start by creating a new folder named notify on your device. This folder will contain everything that will be part of your extension.
Now, you need to make a manifest file that will contain all the information about our extension. Create a file called manifest.json and include the following code:

{
“name”: “Notify!”,
“description”: “A Google Chrome extension!”,
“version”: “1.0”,
“manifest_version”: 3,
“icons”: {
“48”: “/assets/icons/48.png”,
“128”: “/assets/icons/128.png”
}
}

As you can see, so far, it only contains meta-information about your extension, such as its name, description, and version. The manifest_version tells Chrome which version of their extensions API you are using.

Loading the extension
After you have your manifest file in place, you can load up your extension in the Chrome browser:

Loading an extension to Google ChromeLoading an extension to Google Chrome

Open the Extension Management page by navigating to chrome://extensions, or you can also open it from the Extensions menu in the settings.
Once there, enable the Developer mode and use the Load unpacked button to select your extension directory.
Behold thy extension! Now that your extension is loaded, you can improve it step-by-step and observe the changes.
Make sure you add an icon for your extension to the assets/icons/ folder or else a default icon will appear.

Adding a popup user interface
Let’s continue by adding some user interface to the extension from where people can interact with the provided options.
There are multiple ways to do this, such as adding an entire page, but a popup is usually the way to go for most extensions.
To add a popup to the extension, you will have to add this to your manifest.json file:

“action”: {
“default_popup”: “popup.html”,
“default_icon”: {
“48”: “/assets/icons/48.png”,
“128”: “/assets/icons/128.png”
}
},

With this, you tell the extension the location of your popup’s HTML file and the default icons. This is just the default icon as the API allows you to change the icon on the go. For example, if you create a Google PageSpeed test, one can show different icons on the website based on their page rankings.
Extension popupExtension popup
Google Chrome Extension’s Popup
Now, you can add your popup’s HTML code to the file, as we do in our example:

<!DOCTYPE html>
<html>
<head>
<link rel=“stylesheet” href=“assets/css/popup.css”>
</head>
<body>
<div id=“notify-wrapper”>
<div id=“notify-header”>
<h1>Notify!</h1>
</div>
<div id=“notify-containers”>
<div class=“notify-form”>
<label for=“text”>Notification</label>
<textarea name=“text” id=“notify-text” placeholder=“Let’s notify!”></textarea>
</div>
<div class=notify-buttons>
<p>Total: <span id=“notify-count”></span></p>

<button class=“button” id=“notify-reset”>
Reset
</button>
<button class=“button primary” id=“notify-button”>
Notify!
</button>
</div>
</div>
</div>
<script src=“assets/js/popup.js”></script>
</body>
</html>

This HTML file also links to a stylesheet and script to add style and functionality to our popup.
If you are following along, you can get the CSS code from here. We will add JavaScript to the file later in this tutorial.
So far, you have created a Google Chrome extension that has a popup, and it has taken us only a few lines of code. As we said in the beginning, creating a Google Chrome extension is very easy!
Moving forward in this tutorial, we will add functionality to this extension and make it more than just a placeholder.

Using the notifications API
As the extension’s name suggests, it is a notifications extension, so let’s add some!
Before you use some of the APIs, you need to specify permissions for them in the manifest.json file. One of the reasons to do this is so that your extension users know which permissions your extension is asking before installing them.
For notifications, you do it like this:

“permissions”: [
“notifications”
],

“background”: {
“service_worker”: “background.js”
},

You need a service worker for the notification API as it cannot be used directly from the popup.js file.
In the background.js file, you need to add the following code to send a notification:

chrome.runtime.onMessage.addListener( data => {
if ( data.type === ‘notification’ ) {
chrome.notifications.create(
,
{
type: ‘basic’,
title: ‘Notify!’,
message: data.message || ‘Notify!’,
iconUrl: ‘./assets/icons/128.png’,
}
);
}
});

Here, we use the onMessage event listener to get the trigger to push notifications from the popup.
We also use the create method to create a new notification. Notifications can be of various types, but here the “basic” type is used. You should take a look at all the available options.
Now that the create method is in place, you can fire it from the popup.js file like this:

const text = document.getElementById( ‘notify-text’ );
const notify = document.getElementById( ‘notify-button’ );

notify.addEventListener( ‘click’, () => {
chrome.runtime.sendMessage( , {
type: ‘notification’,
message: text.value
});
} );

Here, the sendMessage action is being used to trigger the notification. And voila! We have an extension that triggers a notification.

Chrome Notification APIChrome Notification API

Make sure you are using the latest version of Google Chrome, and have given it permissions to trigger notifications. In short, do not be like me, who spent hours trying to figure out why notifications were not appearing.

Adding a context menu item
As mentioned in the introduction, the context menu is the menu that appears on right click:
Google Chrome Context MenuGoogle Chrome Context Menu
There can be many reasons that your extension might have a context menu item. One prominent example is to select some text with the cursor and then search it on Google.
You can add as many items to the context menu as you want, but if your extension adds more than one item, they will be collapsed under one parent item.
For this, you also need to add permissions to your manifest file:

“permissions”: [
“contextMenus”,
“notifications”
],

Now that you have added permissions for contextMenus, you can add this to your background.js file:

chrome.runtime.onMessage.addListener( data => {
if ( data.type === ‘notification’ ) {
notify( data.message );
}
});

chrome.runtime.onInstalled.addListener( () => {
chrome.contextMenus.create({
id: ‘notify’,
title: “Notify!: %s”,
contexts:[ “selection” ] });
});

chrome.contextMenus.onClicked.addListener( ( info, tab ) => {
if ( ‘notify’ === info.menuItemId ) {
notify( info.selectionText );
}
} );

const notify = message => {
return chrome.notifications.create(
,
{
type: ‘basic’,
title: ‘Notify!’,
message: message || ‘Notify!’,
iconUrl: ‘./assets/icons/128.png’,
}
);
};

The above code also includes the code from the previous step for triggering a notification that is now abstracted into the notify function so it could be reused.
The contextMenus.create action is used to add an item to the context menu. It is hooked to onInstalled as it only needs to be initialized once.
After that, similarly to the previous step, we use contextMenus.onClicked to capture the click and trigger a notification.
Google Chrome's Context MenuGoogle Chrome's Context Menu
It can be a very nifty way to bundle in the functionality of your extension. If you look around at the extensions being used on your browser, you will find many extensions cleverly using this space to enhance the experience of their extension.

Using storage API to store data
Now that your extension has a few features to show off, let’s take a look at the Storage API. Storage API is useful when you want to store some user data to your extension.
There are two types of Storage API: local and sync. Local storage, as the name suggests, is saved in your browser and stays local. In comparison, sync storage allows data to be synced between browsers using the same Google account. For our purposes, we use local storage.
First, you need to add storage permission to your manifest file:

“permissions”: [
“contextMenus”,
“notifications”,
“storage”
],

After this, you can use storage, the storage.local.get and storage.local.set, methods to retrieve or save the data.
You can add the following code to your popup.js file:

const reset = document.getElementById( ‘notify-reset’ );
const counter = document.getElementById( ‘notify-count’ );

chrome.storage.local.get( [‘notifyCount’], data => {
let value = data.notifyCount || 0;
counter.innerHTML = value;
} );

chrome.storage.onChanged.addListener( ( changes, namespace ) => {
if ( changes.notifyCount ) {
let value = changes.notifyCount.newValue || 0;
counter.innerHTML = value;
}
});

reset.addEventListener( ‘click’, () => {
chrome.storage.local.clear();
text.value = ;
} );

This code does two things:

  • It updates the notification count in the popup when we open the popup or the storage value changes. For listening to storage change, storage.onChanged is used.
  • In part, we clear the storage when the user clicks on the reset button.

The above code does the job of getting the latest count and updates it. Now setting up the data remains. For that, you can update our notify function with this:

const notify = message => {
chrome.storage.local.get( [‘notifyCount’], data => {
let value = data.notifyCount || 0;
chrome.storage.local.set({ ‘notifyCount’: Number( value ) + 1 });
} );

return chrome.notifications.create(
,
{
type: ‘basic’,
title: ‘Notify!’,
message: message || ‘Notify!’,
iconUrl: ‘./assets/icons/128.png’,
}
);
};

Here, we get the latest storage data and then update it with the latest count.
Similarly, you can use the chrome.storage.sync API to sync the options between the browsers.

Distributing the extension
Congratulations! You have done it! You have successfully created a Google Chrome extension that uses many different parts of the Google Chrome experience, including:

  • Popups
  • Notifications API
  • Context menu
  • Storage API

If you want to see the code for this extension, you can get it in this Notify GitHub repository.
We all like to show off the great work that we do to the world. Once your extension is complete, you can submit it to the Chrome Web Store for other Chrome users to download.
If you want to explore other options that Google Chrome offers to extension developers, we recommend checking the official documentation.
I hope this article did its part in teaching you how to write a Chrome extension. We are excited to see what you can create, so let us know about your adventures with Google Chrome extension development in the comments section below.
You may also be interested in:


Don’t forget to join our crash course on speeding up your WordPress site. With some simple fixes, you can reduce your loading time by even 50-80%:


Subscribe Now ImageSubscribe Now Image

Layout and presentation by Chris Fitzgerald and Karol K.