Since I've learned that web extensions speak the same languages as websites (HTML, CSS and JavaScript), I've always wanted to give it a try. This post is less a tutorial and more a summary of my experience.
Getting started
Getting started is indeed very easy:
https://css-tricks.com/how-to-build-a-chrome-extension/
I was able to quickly get something working, however, I also quickly faced some limitations that required me to set up a build pipeline in order to:
- use npm modules
- work with promises (browser APIs use callbacks)
- have my extension automatically work both in Chrome and Firefox
- have hot module replacement (HMR)
- use Vue components and TailwindCSS
- in short: have my dev environment as close a possible to my usual environment.
Fortunately, I found this awesome plugin that takes care of all the above-mentioned points.
This plugin scaffolds a web extension project structure and includes the essential webextension-polyfill.
All I had left to do with to set up TailwindCSS and I was ready to code.
Debugging web extensions
I didn't find how to use the Vue devtools extension for debugging, but in my case, logging to the console was sufficient.
To see the console logs when debugging the popup:
- Chrome: Open dev tools, right-click inside the popup and select "inspect"
- Firefox: Click the inspect button on the screen where you added your extension as a temporary extensions [image]
For the settings page, you can set options_page
directly to options.html
, which will open it as a full page.
You can also open the popup as a normal web page by typing its URL: chrome-extension://your_extension_id/popup.html
What about testing?
Thanks to the simplicity of Cypress, I've started to add tests to my projects. However, Cypress currently cannot visit web extension.
Then I found a great blog post about testing web extensions with Jest and Puppeteer. The showcased extension is even built with Vue.
Thanks to that post, I was able to quickly set up Jest. However, I quickly realized that the History API I was using was not mocked by the jest-webextension-mock library🙄
What I ended up doing is to only unit test the main functions with Jest. As fixtures for the tests, I exported a sample browsing history as JSON.
The post later mentioned E2E testing with Puppeteer. I tried to set it up but ran into errors from the Jest integration. At that point, I told myself that I shouldn't spend more time on that topic and move on to finally publishing my extension.
Publishing my extension
Chrome Web Store
The developer dashboard seemed to have recently been redesign. I found it very easy to navigate. There are many contextual info-bubbles that provide useful information. The whole process was very straightforward. I just had to fill out all the required information and pay the entrance fee of $5 to submit my extension for review. Two days later, it was published.
Link to Chrome store page: https://chrome.google.com/webstore/detail/track-it/kjdclicjmhibgokfflkhfccdillnkfbk
Add-ons for Firefox
At Firefox, the submission process was also easy and the review also only took two days. Unlike Chrome, I had to upload the source code. I am actually surprised that Chrome didn't ask for it. Maybe paying the fee with a credit card number provided enough insurance.
Link to Firefox store page: https://addons.mozilla.org/en-US/firefox/addon/track-it/
Now go build your own extension!
Don't fret too much about the fact that there are probably extensions that will be similar/better than yours. With that kind of thinking, you'll never get started. If this doesn't help, take it as a learning exercise.
See my extension: it tracks the time since the last visit to websites... There are plenty of apps that do a similar job and boast more features. But it solved a specific need I had and I use it daily.
You check its source code here:
https://github.com/mornir/track-it
Cover photo by Aron Visuals