Building a Next.js Chrome Firefox Extension

Building a Next.js Chrome Firefox Extension

I was looking for a browser extension that can quickly delete history for specific websites. I share my screen too often at work, I accidentally share some personal websites I visited while typing at the browser address bar.

Although there are countless extensions available, nothing seems to offer the solution I needed, they are too complicated to use and have bad UI/UX. None can meet my requirement of QUICKLY deleting the history of specific websites with a click of a button.

I knew that I was not the only one experiencing this problem so I decided to create my plugin.

So here we discuss the steps in creating a Next.js extension for both Chrome and Firefox.

First, we create our app with the Next.js template by executing the following command:

yarn create next-app

https://react.dev/learn/start-a-new-react-project#nextjs

We use the default for most of the options except for App Router.

Don't select App router or else you will have a bunch of errors like the one below as we are executing the app as a browser extension:

Next as underscores in filenames are prohibited for extension we need to install the gsed package. This package is mainly used for the building stage of our extension where without gsed the filenames created in the /out directory will contain underscores.

If we build and export our app (more on this later) without gsed replacing the underscores in the file name we will have the following issue when we load our extension in the browser :

To install gsed execute the following command in Mac:

brew install gsed

Next, we need to install the npm-watch package.

yarn add -D npm-watch

We need to install npm-watch package to automatically apply the changes in our code to the app while in development.

Now that we have installed the necessary packages we can now update the package.json file specifically the scripts section.

{ 
  "name": "clear-specific-browser-history",
  "version": "0.1.0",
  "scripts": {
    "dev": "next dev",
    "dev:extension": "npm-watch",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "build:extension": "next build && next export && yarn run lint:build",
    "lint:build": "mv out/_next out/assets && gsed -i 's/\\/_next/\\/assets/g' out/**.html",
    "package": "yarn run build:extension && zip -r packages/$(date -u +\"%Y-%m-%dT%H:%M:%SZ\").zip out",
   }
}

Let's focus on build:extension. This command will let us build and export our extension and will call lint:build which will utilize the gsed package we installed earlier. gsed will replace the out/_next directory with out/assets directory and any reference of _next within any **.html file in the out directory will be replaced with assets.

Next, since we are creating a browser extension we need to create a manifest.json file in /public directory.

We need to modify the permissions in manifest JSON to include history and storage as we will save specific websites in the browser's storage and clear their history.

{
  "name": "Clear Specific Browser History",
  "short_name": "clear-specific-browser-history",
  "description": "Removes specific website history from your browser",
  "version": "1.0",
  "manifest_version": 3,
  "action": {
    "default_popup": "index.html",
    "default_title": "Clear Specific Browser History",
    "default_icon": {
      "16": "sweeper-cleaning-icon-16.png",
      "48": "sweeper-cleaning-icon-48.png",
      "128": "sweeper-cleaning-icon-128.png"
    }
  },
  "permissions": ["history", "storage"]
}

"action": { "default_popup": "index.html" } is the default page that you want to display in the popup upon clicking the extension.

We will be building our extension mainly from the /pages/index.html

Because we are using Typescript and the extension will use chrome API to delete history and save data in browser storage. we need to install chrome-types. To install execute:

yarn add -D chrome-types

We then need to open tsconfig.json and insert in types : ["chrome-types"] in compilerOptions.

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "paths": {
      "@/*": ["./*"]
    },
    "types": ["chrome-types"]
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

After the configuration we will need to build and export our Next.js browser extension which will produce an /out directory.

yarn run build:extension

Next, to use our extension in our local browser we need to do the following:

For Chrome/Brave:

  1. Navigate to: chrome://extensions

  2. Switch ‘Developer Mode’ in the top right corner.

  3. Click on the ‘Load Unpacked’ button.

  4. Select your /out directory.

For Firefox:

  1. Navigate to: about:debugging#/runtime/this-firefox

  2. Click the ‘Load Temporary Add-on…’ button.

  3. Go to /out directory and select the manifest.json file.

So here we go our extension is loaded in our local browser.

You can also download the extension in the Chrome Webstore and use it. Will really appreciate it if you leave a positive review. :)

Until next time. Keep learning.

Stay stoked and code. :)


I hope you can voluntarily Buy Me A Coffee if you found this article useful and give additional support for me to continue sharing more content for the community. :)

Thank you very much. :)