How to make a chrome extension FOR BEGINNERS (manifest v3)

How to make a chrome extension FOR BEGINNERS (manifest v3)

Everything you need to know to build your first chrome extension

What this blog will cover-

  • What is the need for Chrome extensions anyway?

  • Should I make a Chrome extension or a web app for my idea?

  • Prerequisites for building a Chrome extension

  • Building a simple extension that displays all your bookmarks

  • Publishing to the Chrome Web Store

There is a lot of outdated content on the internet regarding Chrome extension development. Most of the beginner-friendly tutorials on this topic use Manifest v2 which is deprecated.

So after spending MONTHS learning and building Chrome extensions, I have finally decided to write my own blog so that you don't have to scavenge the internet as I did to get started!

Herald Classic Car GIF by Mecanicus

The need for browser extensions

You may have heard the phrase “There’s an app for that,” and it’s similar to browser extensions. There are tons of things you can do with extensions. You can change the way tabs work, integrate your favorite note-taking service, get Gmail notifications, grammar-check your writing, and even play games.

Series 12 GIF by Doctor Who

There are two common types of extensions. Most either extend the functionality of the browser itself or integrate an existing service with the browser.

Chrome extensions are basically tools that you can add to your Google Chrome web browser (or any Chromium-based browser) to make your online experience better.

Extension or web app?

Chrome extensions are better when you want to do something quickly and easily within your web browser.

Let's say you use a specific website a lot, and you want to access it quickly. With a Chrome extension, you can create a shortcut on your browser's toolbar so you can open the website with just one click. That's super handy!

Also, if you want to block ads while you're browsing, Chrome extensions that are designed specifically for ad-blocking can be more efficient and reliable than web apps that claim to do the same thing.

On the other hand, web apps are better when you need to use a more complex tool or software that requires a lot of processing power and storage. For example, if you need to edit photos or videos, a web app might be a better choice than a Chrome extension.

So, it really depends on what you're trying to do. If you want to add some cool features to your browsing experience, Chrome extensions are the way to go. But if you need to do something more complex, a web app might be a better fit.

Prerequisites

Building a Chrome extension is really easy. Yes, it can be a little daunting at first but trust me it will be alright with time.

So, what do you need to know to build a Chrome extension? Well, you need to know-

  • HTML

  • CSS

  • JavaScript

That's it. If you don't know any fancy libraries or frameworks, then no problem, the Fantastic 3 will do the job.

Okay enough talk, let's make an extension now

I recommend using the rollup plugin which is super useful because it handles most of the manifest.json stuff so you can focus more on the actual development of your extension.

To install the rollup plugin, follow these steps:

  1. Open up your command prompt or terminal and navigate to your Chrome extension project directory.

  2. Run the command npm init to initialize your project with a package.json file.

  1. Install the Rollup plugin as a development dependency by running the command npm install --save-dev rollup @rollup/plugin-commonjs @rollup/plugin-node-resolve

  2. Then run this command: npm i rollup rollup-plugin-chrome-extension@latest -D

  3. Create a rollup.config.js file in the root of your project directory with the following code:

     import commonjs from '@rollup/plugin-commonjs';
     import nodeResolve from '@rollup/plugin-node-resolve';
    
     import { chromeExtension, simpleReloader } from 'rollup-plugin-chrome-extension'
    
     export default {
       input: 'src/manifest.json',
       output: {
         dir: 'dist',
         format: 'esm'
       },
       plugins: [
         // always put chromeExtension() before other plugins
         chromeExtension(),
         simpleReloader(),
         nodeResolve(),
         commonjs()
       ]
     };
    
  4. Modify the manifest.json file to use the Rollup-compiled script by changing the "background" field to "service_worker" and setting the path to the output file, which should be dist/background.js

  5. Add "type": "module" to your package.json.

  6. Run the command npx rollup -c to compile your background script and any other scripts specified in the Rollup configuration.

  7. Test your extension in Chrome by navigating to chrome://extensions, enabling developer mode, and selecting "Load unpacked" to select the dist directory containing your compiled files.

Make sure to add these lines to the package.json inside the scripts object so you don't have to run npx rollup -c again and again 😉

"dev": "rollup -c -w",
"build": "rollup -c",
"release": "cross-env NODE_ENV=production rollup -c"

The one thing to keep in mind while making any extension is the manifest.json file. Now, when using the Rollup plugin for Chrome extension development, the manifest.json file should include the following fields:

"name": used to give your Chrome extension a name. This name would be visible when in the Chrome Web Store and the browser's extensions page.

"version": The version number of the extension. You would update this every single time you upload a new version of your extension to the Chrome Web Store.

"description": A short description of the extension.

"icons": An object that defines the icons for the extension. The recommended sizes are- 16x16, 32x32, 48x48, and 128x128.

"action": An object that defines the browser action for the extension, which is a clickable button in the browser's toolbar that triggers an action in the extension.

"background": An object that defines the background scripts or service worker that runs in the background of the extension. So you might want to do tasks like- communicating with external servers, running code when the extension is installed or updated, listening for events and triggers, or managing long-running processes such as downloading large files or processing large amounts of data.

"content_scripts": An array specifying content scripts to be injected into specific web pages. With this, you can do stuff like- injecting custom CSS styles or JS, adding custom UI elements or parsing and extracting data from web pages. Pretty cool, right?

"permissions": An array specifying the permissions required by your extension. This would be used when you want to access external resources like an API or access user's data like bookmarks, history or browser settings, etc.

"manifest_version": Set this to 3, as the Rollup plugin only supports manifest version 3.

  • make a simple extension through gpt's help

  • include pictures/illustrations

Here's what a typical manifest.json looks like while using the rollup plugin-

{
  "manifest_version": 3,
  "name": "My Extension",
  "version": "1.0",
  "description": "This is my extension.",
  "icons": {
    "16": "icons/16.png",
    "48": "icons/48.png",
    "128": "icons/128.png"
  },
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["https://example.com/*"],
      "js": ["content.js"]
    }
  ],
  "permissions": ["storage", "activeTab"],
  "action": {
    "default_title": "My Extension",
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/16.png",
      "32": "icons/32.png",
      "48": "icons/48.png",
      "128": "icons/128.png"
    }
  }
}

Building a simple chrome extension

Now that the basic stuff's out of the way, let's make a very simple extension that displays all your bookmarks.

  1. Follow the first six steps from the previous example to create a new folder for your extension and install the required packages.

  2. Create a new file called popup.html in a src folder with the following contents:

<!DOCTYPE html>
<html>
  <head>
    <title>Bookmark Tracker</title>
    <style>
      body {
        font-family: sans-serif;
        font-size: 14px;
        margin: 0;
        padding: 8px;
      }

      h1 {
        margin-top: 0;
      }

      ul {
        list-style: none;
        margin: 0;
        padding: 0;
      }

      li {
        margin-bottom: 8px;
      }
    </style>
  </head>
  <body>
    <h1>Bookmarks</h1>
    <ul id="bookmarks"></ul>
    <script src="popup.js"></script>
  </body>
</html>
  1. Create a new file called popup.js in the folder with the following contents:
function updatePopup() {
  chrome.bookmarks.getTree((tree) => {
    const bookmarks = tree[0].children[0].children;
    const bookmarksList = document.getElementById('bookmarks');

    bookmarksList.innerHTML = '';

    bookmarks.forEach((bookmark) => {
      const link = document.createElement('a');
      link.href = bookmark.url;
      link.textContent = bookmark.title;
      link.target = '_blank';

      const item = document.createElement('li');
      item.appendChild(link);

      bookmarksList.appendChild(item);
    });
  });
}

document.addEventListener('DOMContentLoaded', () => {
  updatePopup();
});
  1. Modify the manifest.json file to include the popup:
{
  "manifest_version": 3,
  "name": "Bookmark Tracker",
  "version": "1.0.0",
  "description": "Keeps track of your bookmarks",
  "permissions": ["bookmarks"],
  "action": {
    "default_popup": "popup.html"
  }
}
  1. Run the command npm run dev to compile your background script and any other scripts specified in the Rollup configuration.

  2. Test your extension in Chrome by navigating to chrome://extensions, enabling developer mode, and selecting "Load unpacked" to select the dist directory containing your compiled files.

And, voila ✨ You just made your first Chrome extension! 🥳

Getting some errors? It might be because of the following reasons-

  1. You might have forgotten to add "type": "module" at the end of the package.json file.

  2. You might be running npm run dev before specifying the command in the "scripts" object in "package.json". Your "package.json" should look like this-

     {
       "name": "bookmark-tracker",
       "version": "1.0.0",
       "description": "",
       "main": "index.js",
       "scripts": {
         "dev": "rollup -c -w",
         "build": "rollup -c",
         "release": "cross-env NODE_ENV=production rollup -c"
       },
       "author": "",
       "license": "ISC",
       "devDependencies": {
         "@rollup/plugin-commonjs": "^25.0.0",
         "@rollup/plugin-node-resolve": "^15.0.2",
         "rollup": "^3.21.7",
         "rollup-plugin-chrome-extension": "^3.6.12"
       },
       "type": "module"
     }
    
    1. You might have loaded the src folder instead of dist folder.

Publishing to the Chrome Web Store

So you've built the Chrome extension that you've always wanted to build and now you want other people to use it and get benefited?

Well, it's easy.

Here's what you need to do to make your extension public.

  1. Run npm run release

  2. Pack your extension in a .zip file.

  3. Go to the Chrome Web Store Developer Dashboard and sign in with your Google account.

  4. Click on the "Add new item" button.

  5. Read and accept the Developer Agreement.

  6. Fill out the required fields, including the name and description of your extension, and upload a promotional image and screenshots.

  7. Choose a category and language for your extension.

  8. Upload your .zip file.

  9. Set the price and publication options for your extension (free or paid, public or unlisted).

  10. Submit your extension for review.

  11. Wait for the review process to complete. This can take up to several days.

Once your extension is approved, it will be published on the Chrome Web Store and available for download by users 🚀


And that's it for this tutorial! I hope you like it 😃

By the way, I built this extension that helps manage your tabs by grouping them into sessions which you can use anywhere!

Give it a try: TabMaster - Chrome Web Store (google.com) (to use this extension make sure you're signed to your browser)

Follow me on Twitter: https://twitter.com/zaidahmad25

Bye and have a nice day! 👋