Creating a Chrome Extension with NextJS

So, you've delved into writing your own Chrome extension. Maybe you've even already made one, but you still have a question: How can I use the current technology to do this? Well, as it turns out, it only takes a few extra steps!

In this tutorial, I am going to go over how to create a Chrome extension using NextJS! While this guide is tailored specifically for NextJS, I presume it would work well for Nuxt as well, but please let me know in the comments!

First things first

First up, we are going to create our NextJS application!

npx create-next-app && cd next-app
# or
yarn create next-app && cd next-app

At this point, you can install any extra dependencies you may wish to add (like Typescript or TailwindCSS).

This will set up some defaults for you, but we need to change them. First off, to build a NextJS app for a chrome extension, we need to use "next export". To do this, we are going to edit the scripts in package.json:

{
    "scripts": {
        "build": "next build && next export"
    }
}

You won't need the other two scripts. Let's remove them. You can also go in and delete your `pages/api` directory, as we won't be using them.

Next, we need to create a "manifest.json" and place it in "public/". You will also need icons for this. There are several generators for this that you can find only, but here is a starter:

{
    "manifest_version": 2,
    "name": "My New Extension",
    "short_name": "my-extension",
    "version": "1.0.0",
    "description": "My Extension",
    "icons": {
        "16": "icons/icon-16.png",
        "32": "icons/icon-32.png",
        "150": "icons/icon-150.png"
    },
    "permissions": [],
    "browser_action": {
        "default_title": "My Extesnion",
        "default_popup": "index.html"
    }
}

Building the app!

From here, we can run "yarn build". This will create our app and export it to a static site in "out/". We'll run into a problem with this though, in that chrome extensions can't (for some reason) have underscores in their paths.

Let's do some more tweaking to fix that! We will add a new script to "scripts" that change the directory in the code and the directory structure.

{
    "scripts": {
        "build": "next build && next export && npm run prepare",
        "prepare": "mv out/_next out/assets && sed -i 's/\\/_next/\\/assets/g' out/**.html"
    }
}

Sweet! Now double-check the "out" directory and make sure everything looks right.

If everything looks good, you can go ahead and load the "out/" directory into chrome!

A Quality of Life Thing

I'd be ending this a little short if I didn't suggest improving the developer experience of this. Having to run "yarn build" every time you make a change is annoying.

Enter: "npm-watch"

This is a convenient package that watches files based on different settings you give it and then runs an "npm script".

Below you'll find my suggested configuration for this. You'll want to tweak this based on your project settings.


{
  "watch": {
    "export": {
      "patterns": [
        ".",
        "styles/**",
        "pages/**",
        "public/**"
      ],
      "ignore": [
        "out",
        "node_modules",
        ".next"
      ],
      "extensions": [
        "js",
        "json",
        "lock",
        "tsx",
        "ts"
      ]
    }
  },
  "scripts": {
    "build": "next build && next export && npm run prepare",
    "prepare": "mv out/_next out/assets && sed -i 's/\\/_next/\\/assets/g' out/**.html",
    "watch": "npm-watch"
  }
}

Then, just run "yarn watch"!

That's it! If you have any problems getting this going, please reach out in the comments, or come chat with me in discord at https://discord.gg/FUhmvK7. I hope this has been helpful!

Don't forget to come and watch me stream either: https://twitch.tv/CryptikLemur.

I do programming streams during the day on Tuesday, Wednesday, and Thursday, so come on by!

Related Posts

jQuery: Roll to Next Input

I was looking for a way to have an input, that when you change, would roll to the next input. The project I'm working on has a page based system, so each page has its own fieldset. When the last field is completed, I wanted it to automatically roll to the next page. I also wanted functionality for zip code, and phone number fields, that would roll to the next input after 5 digits on zip, or roll to the next piece of the phone number field.