A Step-by-Step Guide to Creating a Chrome Extension with React

Building a Chrome extension with a React app developed using TypeScript and bundled with Webpack offers a modern approach to browser extension development. In this blog, I will guide you through the process of creating a Chrome extension with the npx create-react-app template in TypeScript and bundling the app with Webpack. Additionally, we will utilize the latest version of the Chrome extension manifest, Manifest V3.

Prerequisites

Before we dive into the development process, ensure you have a basic understanding of React and its core concepts, as well as a fundamental of JavaScript and HTML.

Additionally, you'll need the following tools.

  • Google Chrome
  • Visual Studio Code
  • Node.js and npm (Node Package Manager)

Step 1. Create a React App

To begin, we need to create a new TypeScript React project. Open your terminal or command prompt and run the following command. This will set up a new React project with all the necessary dependencies.

npx create-react-app react-chrome-ext --template typescript

TypeScript React

Let's update the App.tsx file to be a basic React component that displays "Hello! This is an article on creating a Chrome Extension with React."

import './App.css';

function App() {
  return (
    <div className="App">
      <div className="">
        Hello! This is an article on creating a Chrome Extension with React.
       </div>
    </div>
  );
}

export default App;

Next, update index.tsx to create a root element in the DOM and append our app to it.

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";

const root = document.createElement("div");
root.className = "container";
document.body.appendChild(root);
const rootDiv = ReactDOM.createRoot(root);
rootDiv.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Let's add some minimal CSS to App.css.

.App {
    color: white;
    text-align: center;
}

.container {
    width: 25rem;
    height: 25rem;
    background-color: rgb(107, 0, 128);

}

Step 2. Incorporate Webpack

Next, let's install the required dependencies to bundle our React app. Execute the following commands in your terminal.

npm install --save-dev webpack webpack-cli copy-webpack-plugin css-loader ts-loader html-webpack-plugin ts-node

The command npm install --save-dev webpack webpack-cli copy-webpack-plugin css-loader ts-loader html-webpack-plugin ts-node does several things.

  1. webpack and webpack-cli: These are the core packages for bundling JavaScript files in your project. webpack-cli provides the command line interface for webpack.
  2. copy-webpack-plugin: This plugin allows you to copy files and directories during the build process. It's useful for tasks like copying static assets (images, fonts, etc.) into the build directory.
  3. CSS-loader: This webpack loader allows you to import CSS files into your JavaScript files. It enables webpack to understand and process CSS files.
  4. ts-loader: This loader allows webpack to compile TypeScript files (*.ts and *.tsx) into JavaScript.
  5. html-webpack-plugin: This plugin simplifies the process of creating HTML files to serve your webpack bundles. It generates an HTML file with references to your bundled JavaScript files.
  6. ts-node: This is a TypeScript execution and REPL for Node.js, allowing you to execute TypeScript code directly without prior compilation.

By installing these dependencies, you're setting up your project to use webpack for bundling, along with loaders and plugins necessary for handling TypeScript, CSS, and HTML files.

The create-react-app template doesn't include a Webpack configuration file by default. Therefore, we need to create one ourselves. Start by making a new file named webpack.config.js in the root directory of your project. Then, add the following code.

const path = require("path");
const HTMLPlugin = require("html-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");

module.exports = {
  entry: {
    index: "./src/index.tsx",
  },
  mode: "production",
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: [
          {
            loader: "ts-loader",
            options: {
              compilerOptions: { noEmit: false },
            },
          },
        ],
        exclude: /node_modules/,
      },
      {
        exclude: /node_modules/,
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
  plugins: [
    new CopyPlugin({
      patterns: [{ from: "manifest.json", to: "../manifest.json" }],
    }),
    ...getHtmlPlugins(["index"]),
  ],
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
  },
  output: {
    path: path.join(__dirname, "dist/js"),
    filename: "[name].js",
  },
};

function getHtmlPlugins(chunks) {
  return chunks.map(
    (chunk) =>
      new HTMLPlugin({
        title: "React extension",
        filename: `${chunk}.html`,
        chunks: [chunk],
      })
  );
}

Webpack configuration

This configuration file establishes the entry point for our application (the index.tsx file), specifies the output file name, and defines the TypeScript loader, style loader, and output directory.

With webpack configured, let's update your package.json file to include the following scripts.

  "scripts": {
    "build": "webpack --config webpack.config.js",
    "watch": "webpack -w --config webpack.config.js"
  }

With these scripts, you can build your extension by executing the npm run build command, or run Webpack in watch mode with npm run watch.

Step 3. Create the Manifest File

The manifest file serves to define the metadata and permissions for a Chrome extension. Create a new file named manifest.json in the root directory of your project and input the following code.

{
    "version": "1.0.0",
    "manifest_version": 3,
    "name": "React Chrome Extension",
    "description": "This is a Chrome extension built with React",
    "action": {
        "default_popup": "js/index.html",
        "default_title": "React Chrome Extension"
    }
}

This manifest file outlines the extension's name, version, and description. Additionally, it defines the popup window.

Step 4. Compile the App

To finalize, execute the npm run build command in your terminal to compile your extension. Once the script completes, a new /dist folder will be generated at the root of our app.

Compile the App

Step 5. Load the extension

To load your extension into Chrome, open Chrome and navigate to the Extensions page by typing chrome://extensions into the address bar. Then, click the "Load unpacked" button and select the dist directory in your project.

Load unpacked

Chrome

Extensions

Verify your extension by refreshing the Extensions page and clicking on the extension icon.

 Extensions page

Conclusion

In conclusion, building a Chrome extension with a React app using TypeScript and bundling with Webpack offers a modern and efficient approach to browser extension development. Throughout this guide, the essential steps have been covered, from setting up the development environment to creating the manifest file and compiling the extension. By following these steps, you can create feature-rich Chrome extensions tailored to your specific needs. With the power of React, TypeScript, and Webpack, the possibilities for building innovative browser extensions are limitless. Happy coding, and may your extensions bring value and convenience to users across the web!

Feel free to ask any questions or share your thoughts in the comments section below. I'm here to help!