Creating a Chrome Extension with React

By Aman Kumar

February 5th, 2021

Last week I started building a Chrome extension for a product. The extension was built with React as a view engine to render a popup. So I thought to document it to make anyone getting started on this to get along.

In this blog, We will go through the process of building a Chrome extension using React. After this, you can add more functionalities to it very conveniently.

Link for Github Repository: https://github.com/onlyoneaman/chrome-extension-react

So Let’s get started.

Features of the extension

This extension can access your active tab and change the background colour of the page.

BeforeBefore

AfterAfter

Extension Basic

Before diving into the details, let’s look a little on the basic structure of an extension of the chromium-based browser.

This extension structure works on Chrome, Edge and Brave, and maybe other Chromium-based browsers I don’t know.

There’re several key parts of an extension:

Structure of a Chrome extensionStructure of a Chrome extension

Manifest

the manifest describes what’s in the source package. It specifies where browser could find background, content script, popup and options pages. As well as it describes permissions required by the extension.

Background

A piece of code launched when the extension launched, and won’t be terminated until extension removed or browser shutdown.

Background code has access to all Chrome APIs, and other parts are limited. But the background doesn’t have a UI and can not access DOM.

Popup

The UI popped up while user clicks on ‘browser action’ which is your extension icon button right to the browser address bar.

Most extensions need a popup as an entry.

Options

It’s an optional part of the extension. Not all extensions have an options page. It is used as a configuration UI for the extension. Your extension has to provide an entry for it.

If you have some something complicated to be configured, you need this.

Content Script

The content script is a piece of JavaScript which runs in a tab with a specific URL. The URL pattern is defined in manifest.json. If the URL matched with which is specified in manifest.json, the browser will launch the content script. It will be terminated while the URL changed, or tab closed.

If you want to manipulate DOM, you need the content script.

So you should already have an idea of what these parts are doing now.

What part are involved in this extension?

Background: not in this tutorial, but there’s an empty background.js in the repo for future use.

Popup: Yes. That’s the focus of this article. I will show you how to write a Popup in React.

Options: no.

Content script: no.

Let’s begin

Step 1. Create a directory for the extension

mkdir chrome-extension-example
cd chrome-extension-example

Step 2. Create a React app inside the directory

npx create-react-app extension

*I’m assuming you already installed **node **and **npm *on your machine.

This will create a regular React app.

Step 3. Create manifest.json

Create a manifest.json file in the root of the extension

touch manifest.json

Step 4. Modify manfiest.json

Now, open the extension in the code editor of your choice and update manifest.json:

Step 5. Images for logo

Download the zip file for logos and extract at the root of the extension download link:

Step 6. Add the script in package.json

In the package.json file of extension, add the following in script:

"move": "yarn build && rm -rf ../static && mv build/static ../static

We will use this script to build our app. Also, since all resources like images and files need to be at the root of the extension not the react app, we move the static folder in build to the root of extension.

Step 7. Updating Code in React App

In our App, we need a button when clicked a function changeColor.

Next, create a function main.js in src/ in react app with the following contents. Here, we have a function changeColor called when change color button is called. It sets green color in Chrome storage, and gets the current active tab and execute script over this tab.

Notice the /global chrome/ on top of this file. This is to avoid linting issue with Eslint. If you miss this, your react app will return error.

Step 8. Add script to change background color

Create a folder scripts at the root of extension, and create a file changeBgColor.js with the following contents

chrome.storage.sync.get("color", ({ color }) => {
  document.body.style.backgroundColor = color;
});

This much is enough in the react app, we won’t be touching css here you can play with it if you want.

Step 9. Build and load into Chrome

In the extension directory (of your React app), run

npm run move 

Now load the Chrome extension directory as an unpacked extension in chrome://extensions.

These options are available if your developer mode is ON.

Click on the change button color and check if that is working. If the extension is working correctly. You would see:

Working Version of extensionWorking Version of extension

If you don’t see the above, there is some error in the code or execution check the errors for the Chrome extension.

If you see an error such as:

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' blob: filesystem:".

Check the next step which deals with fixing this. Else, there has been some error try debugging it won’t be that hard.

Some other possible errors include:

  • Folder or file not present in appropriate place.

  • Your system or code editor default setting or linter might have some issue with the code.

Step 9. Adding sha keys for security

Two reasons why you should focus on this step carefully.

Your extension is showing security policy directive error and you see the screen as following after clicking on the extension.

Extension not workingExtension not working

You may face this error in future and thus can look on to how to solve this.

So, Chrome won’t allow you to execute inline javascript code. Thinking you haven’t added any inline code? Remember the build generated by React has that for you. So, We have to configure the extension to allow inline execution.

This can be done by adding a specific keyword in content_security_policy header in manifest.json.

This will be the sha-key of the inline function generated by chrome which you can find in the error itself.

So, copy this hash and paste in the content security policy header as shown:

'content_security_policy': "script-src 'self' 'sha256-fdAfMKZtCTRPKMRznGwonJHC++vCCrQS7XFnVrzSXAE=';"

And this will solve the issue. If there are more error like this you will have to add sha-keys for each of those functions.

Try reloading the extension in chrome://extensions and the extension would work now.

The React extension is running good. 😃

Conclusion

And there we have it! We’ve created our very own (basic) Chrome extension. Now you hopefully have the tools needed to create a base from which you can build from.

Update 08/03/2021: Recently, Chrome has deprecated the use of action in manifest version less than 3. Earlier, it was recommended only to use action in manifest v3 not a necessity. We are still keeping the repo at manifest v2 due to CSP Issues in v3 and changing the action to browserAction will work alone. Just change the action in manifest to browserAction to make the extension work if you are facing the issue.



Continue Learning