In this post, you will learn how to create your first chrome extension, install it in every major browser, and get the basis that will guide you next!
The extension we are about to create, will show a random joke. The name of the extension will be, Joker.
Step 1
Prepare a new folder joker
. Start by creating manifest.json
. It is a file that is required by any extension. It's the entrypoint. Put the following content into the file:
{
"manifest_version": 2,
"name": "Joker",
"description": "Why so serious?",
"version": "1.0",
"icons": { "128": "joker.png" },
"browser_action": {
"default_icon": "joker.png",
"default_popup": "popup.html"
}
}
Most things are self-explanatory.
Let's look more closely at "browser_action"
. This specifies, that the extension will open a popup once we click on the extension icon, which will be added to the browser's toolbar after the extension is installed. In the popup, we will display a random joke.
To see the full list of possible attributes, that you can specify in this file, see here.
Let's continue now by creating the files we specified in the manifest.
Step 2
Open flaticon and look for an icon you would like to use for the extension. Make sure the icon is of size 128, png format. Save the icon as joker.png
.
Step 3
Create popup.html
with the following content:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Joker</title>
<link rel="stylesheet" href="popup.css">
<script src="popup.js"></script>
</head>
<body>
<div id="joke"></div>
<div id="one-more">Haha, one more!</div>
</body>
</html>
Step 4
Now, create popup.css
and make it pretty! 💁♀️
body {
margin: 0;
padding: 1em;
min-width: 350px;
background: #9550bb;
color: white;
font-family: Helvetica, Arial, sans-serif;
font-weight: bold;
font-size: 12px;
}
#joke {
font-size: 3em;
}
#one-more {
display: inline-block;
cursor: pointer;
font-size: 1.5em;
margin-top: 1em;
border-bottom: 2px solid;
}
#one-more:hover {
border-bottom-color: transparent;
}
Step 5
Create popup.js
, the last file we need.
const getJoke = async () => {
const joke = await fetch("https://icanhazdadjoke.com", { headers: { "Accept": "application/json" } })
.then(response => response.json())
.then(json => json.joke)
.catch(() => "No Internet Connection");
document.getElementById("joke").innerHTML = joke;
}
document.addEventListener("DOMContentLoaded", () => {
getJoke(); // initial joke
document.getElementById("one-more").addEventListener("click", getJoke);
});
Step 6
Check that you have all the files. See http://github.com/penge/joker for reference.
You should have:
- manifest.json
- joker.png
- popup.html
- popup.css
- popup.js
Step 7
It is time to try the extension in every browser!
Chrome:
- Open
chrome://extensions
- Click Load unpacked (click Developer mode if you don't see the button)
- Open folder
joker
Firefox:
- Open
about:debugging#/runtime/this-firefox
- Click Load Temporary Add-on...
- Open any file in folder
joker
Edge:
- Open
edge://extensions
- Click Load Unpacked (click Developer mode if you don't see the button)
- Open folder
joker
Opera:
- Open
opera://extensions
- Click Load unpacked (click Developer mode if you don't see the button)
- Open folder
joker
Step 8
Enjoy the extension! 🙂
FAQ
1. Will my extension work on any OS? Any browser?
Your extension will work on any common OS (Windows, Linux, OSX, Chrome OS) and any Chromium-based browser (Chrome, Edge, Opera) that supports Extensions API, or Firefox, which is compatible to a large extent when using WebExtensions API (a common API). Minimal to no changes should be needed to make it compatible, and look the same elsewhere.
2. What are some good resources to start?
You will be pretty good to go with:
- https://developer.chrome.com/extensions
- https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions
3. Where can I get some inspiration? What to create? What is possible?
Check the list of all Chrome APIs, that will give you a good overview about the available APIs, and also the sense of what they can do, and you can create based on.
Check Manifest File Format Summary, as this is the main file in every extension.
4. What is the folder structure?
Every extension needs to have manifest.json
in the root. Any other files can be organized in any way you like.
5. How to publish the extension? How does it work?
Every browser has the store:
- Chrome Web Store ($5 one time fee; slow reviews)
- Firefox ADD-ONS (no fee)
- Edge Add-ons (no fee)
- Opera addons (no fee; instantly published)
You then pack your extension (zip
or crx
) and submit it for a review. When approved, it is published.
6. Is there a way to get the extension published faster?
Once the extension is in a pending review, you cannot interrupt or speed up that process (Web Store). What you can do, is to develop your extension in a certain way, that makes reviewing it much faster. Here are some tips:
have a good documentation, describe all the required and optional permissions, why they are needed, and what functionality they provide
avoid build step (no transpiling, minification, obfuscation), if possible
7. What are required and optional permissions?
Permissions allow the extension to use some useful APIs and build some features on top of them. Permissions are defined in manifest.json
. The most common are "storage" and "tabs". See the complete list here.
Specifying the permission as Required means, it is needed at all times to function properly (or to provide the basic functionality). Optional permissions, on the other hand, are a good practice to say, these permissions are needed only when user turns on some additional functionality (through a Checkbox).
8. What is the best way to develop an extension?
There is no best way. Align the toolkit to what you need. It can be any of: JavaScript, JavaScript modules, Typescript, with dependencies, without, with bundler, without.
Benefits of not having a build step, are obvious: easier and faster to develop, debug, publish, review.
9. Where do I find some good icons?
See flaticon.
10. Does the extension have to have a popup? What other kind of UI is possible?
Popup is optional. Actually, any UI is optional. There may be an extension that has no UI at all!
Besides popup, other ways to display something, is in the new tab (like when the user clicks on the Toolbar icon), or override any new tab with some content.
Let's see how Joker can be improved!
- more jokes (more APIs)
- jokes by a category
- offline jokes (json file)
- save the joke to favorites (can view later)
- share the joke (if from API)
- themes
Thank you for reading! I hope you had great fun and learned something new! 🙂
Top comments (7)
Great work and appreciating it.
Did a quick mock up in style out of curiosity.
Very nice!
For a feedback , I think it would be better tweak the styles since you allready published it into stores.
I like the icon of Joker you used. About the design, I am open to suggestions. There could be several themes also (or at least Light and Dark), and the preferred could be selected in Options. This could also be a nice tutorial on how to use "storage".
Amazing!
Thanks! :)) Maybe in the next article, we could look at "storage". It's one of the most useful APIs to store/retrieve configuration, or even listen to changes (listeners).
Waiting for it!