React Browser Extension
Introduction
Creating a browser extension for Chrome using React is a great way to get started with developing for the web. I liked browser extensions already before I knew how to create one myself. There were times when I had 20 extensions added to my Chrome at the same time. Of course I was not using all of them but it shows that there really are a lot of tools and features for sites already out there for you to explore or get inspired. The cool thing about them is that you can basically use them to create content on any site that helps you make decisions or shows certain metrics that nobody else can. For example I created a tool that helped me to rate the rarity of certain NFT collections. But that is just one example. You might want to compare prices on amazon or show data in graphs. With browser extensions you can do that.
How to get it done
In the following I will show you the exact steps how to create a browser extension for Chrome using React.
Getting started
Create a new folder and run
npm init
Create the initial folder structure and add the following files:
Then inside these folders create the following files:
Manifest file
For a browser extension to work it needs a manifest.json
file. This file is a json file that describes the extension. The manifest file is the first file that gets loaded
when the extension is initialized and it tells the browser what to do and where to find the files that it needs. You can find out more about that on the Chrome
developer site.
// manifest.json
{
"name": "Getting Started Example",
"description": "Build an Extension!",
"version": "1.0",
"manifest_version": 3
"browser_action": {
"default_popup": "popup.html"
},
}
This is the most basic version of the manifest file. It is basically the getting started version from the Chrome developer site with the addition of the browser action.
popup.html file
Next we create the content of the popup.html
file that will be shown when the browser action is clicked.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scal=1.0" />
<title>Document</title>
</head>
<body>
<div id="react-root"></div>
</body>
</html>
install react
npm i --save react react-dom
popup.jsx file
In our popup.jsx
file we will create the content that will be shown inside the popup.html file that we created. So we will define the components that will be rendered
inside the react-root div in our popup.html file.
import React from "react";
import { render } from "react-dom";
function Popup(props) {
return (
<div className="popup">
<div className="popup_inner">{props.children}</div>
</div>
);
}
render(<Popup />, document.getElementById("react-root"));
Webpack
Since the browser is not able to load the files directly we need to use webpack to bundle the files first. The reason for this is that the browser can not simply open the files directly as they are node and not javascript files. Instead we will need to create static hmtl and javascript files for the browser to be able to load our extension. The process for this is relatively simple but the setup of webpack can be a bit of a pain. So we will try to keep it simple.
First create a webpack.config.js file in the root of the project.
// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
// pages to convert
entry: {
popup: "./src/popup.jsx",
// further pages to be converted to js
},
// output files and output path
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js",
},
module: {
rules: [
{
// loader will execute for js or jsx files
test: /\.(js|jsx)$/,
// exclude node_modules from conversion
exclude: /node_modules/,
// babel loader to convert jsx to js
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"],
},
},
},
],
},
};
For the code above to be working we will need to do two things.
- First we need to install the
babel
andbabel/preset-react
packages.
npm i --save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react
- Second we need to add the a new script in the package.json file for the webpack command to build the extension.
// package.json
...
"scripts": {
"build": "webpack --config webpack.config.js"
},
...
Now our conversion would already work and you can test that by writing npm run build
in the terminal. You should see the extension beeing build in the dist folder.
The issue that we still have with the webpack setup is that the extension like this is not able to load the files directly, because it is missing its center piece of the
extension which is the popup.html
file and all our static files as well. We could add the popup.html
file to the dist
folder manually every time we build but as we are still using webpack we
can use the CopyPlugin
to copy the files from the public folder to the dist
folder. And use the HtmlWebpackPlugin
to add the popup.html
file to the dist
folder.
Lets first install our dependencies.
npm i --save-dev copy-webpack-plugin html-webpack-plugin
To make the rest happen we need to add the CopyPlugin
and the HtmlWebpackPlugin
to the plugins
array in the webpack.config.js
file.
// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
// pages to convert
entry: {
popup: "./src/popup.jsx",
// further pages to be converted to js like background.js
},
// output files and output path
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js",
},
module: {
rules: [
{
// loader will execute for js or jsx files
test: /\.(js|jsx)$/,
// exclude node_modules from conversion
exclude: /node_modules/,
// babel loader to convert jsx to js
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"],
},
},
},
],
},
// plugins
plugins: [
new HtmlWebpackPlugin({
template: "./src/popup.html",
filename: "popup.html",
}),
new CopyPlugin({
patterns: [{ from: "public" }],
}),
],
};
Open Extension in Chrome
To load the extension in Chrome we need to open the chrome://extensions
page in Chrome and click or the extension icon in your extensions section in the Browser.
- Enable developer mode in Chrome
- Load unpacked extension in Chrome
Now you have your extension loaded in Chrome and you can click it in the top right corner of the browser to see the popup.
Enhance your Extension from here
How to enhance your extension from here?
- You cann add new pages to the extension like background.js. If you want to do so you need to remember to add those files to the
entry
object in thewebpack.config.js
file and yourmanifest.json
file. - You can add new components and import them in the popup.jsx file.
Bonus Dev Tip
Open the adress chrome-extension://<extensionid>/popup.html
in your browser. Exchange the <extensionid>
with the extension id of your extension. You
can find the ID generated by Chrome on your extensions page. See the image above.
With this setup you can now debug your extension in Chrome just like a regular webpage.
- Affiliate Disclaimer
- Disclaimer:
Links on the site might be affiliate links, so if you click them I might earn a small commission.