How to Build a React Extension for Chrome: A Beginner’s Guide

react extension chrome

Building a Chrome Extension with React

React can make it easier to build polished, interactive interfaces for a Chrome extension. You can use it for a popup, an options page, or an interface injected into a webpage. Chrome still handles extension-specific features—such as permissions, tabs, and storage—through its Extension APIs, while React manages the interface.

What You Need to Know

A Chrome extension is made up of files described by a manifest.json file. A React project adds a build step that turns your source code into browser-ready files. The finished files, not the development project, are what you load into Chrome.

Most new extensions use Manifest V3. In this version, extension pages and scripts follow Chrome’s extension security rules. For example, remote JavaScript cannot be loaded into an extension page; JavaScript must be included in the packaged extension.

Create a React Project

One simple way to get started is with Vite, a tool for creating and building frontend projects. Run these commands in a terminal:

npm create vite@latest my-extension -- --template react

cd my-extension

npm install

For a basic popup extension, configure the project so the production build places the extension files in a folder such as dist. The manifest.json file must be included in that folder. For example, a Vite configuration can copy it during the build:

import { defineConfig } from 'vite'

import react from '@vitejs/plugin-react'

import { resolve } from 'node:path'

import { copyFileSync } from 'node:fs'

export default defineConfig({

plugins: [

react(),

{

name: 'copy-extension-manifest',

closeBundle() {

copyFileSync('manifest.json', 'dist/manifest.json')

},

},

],

base: './',

build: {

rollupOptions: {

input: {

popup: resolve(__dirname, 'index.html'),

},

},

},

})

Using base: './' helps the built page find its JavaScript and CSS files when Chrome loads it as an extension.

Add a Manifest

Create a manifest.json file in the project root. This example defines a popup and requests access to Chrome’s local storage:

{

"manifest_version": 3,

"name": "React Starter Extension",

"version": "1.0.0",

"description": "A simple Chrome extension built with React.",

"action": {

"default_popup": "index.html"

},

"permissions": ["storage"]

}

Only request permissions your extension actually needs. If your extension interacts with websites, you may also need to declare appropriate host permissions or use a content script. Keep access as limited as possible.

Build the Popup Interface

The popup is an extension page, so you can use familiar React components and CSS. Here is a small example that saves a note using Chrome’s storage API:

import { useState } from 'react'

function App() {

const [note, setNote] = useState('')

const [saved, setSaved] = useState(false)

async function saveNote() {

await chrome.storage.local.set({ note })

setSaved(true)

}

return (

<main>

<h1>Quick Note</h1>

<textarea

value={note}

onChange={(event) => {

setNote(event.target.value)

setSaved(false)

}}

placeholder="Write a note..."

/>

<button onClick={saveNote}>Save</button>

{saved && <p>Note saved.</p>}

</main>

)

}

export default App

To use the Chrome API in a React project, include Chrome’s extension type definitions during development. The browser APIs are available when the code runs inside Chrome, but they will not work in a regular webpage without suitable mocks or checks.

Popup, Options Page, or Content Script?

  • Popup: Opens when a user clicks the extension icon. It works well for short tasks and quick controls.
  • Options page: Provides a place for users to configure extension settings. It can be built as another React page.
  • Content script: Runs in the context of a webpage and can read or modify parts of that page, subject to permissions and Chrome’s security boundaries.
  • Service worker: Handles background events, such as messages or alarms. In Manifest V3, background logic commonly runs in an extension service worker.

These parts have different roles. A content script should not be treated as a regular extension page, and it cannot directly use every Chrome API. When a content script needs an operation that requires extension privileges, it can communicate with the service worker or another extension page using Chrome’s messaging APIs.

Build and Test the Extension

  1. Run npm run build to generate the production files.
  2. Open chrome://extensions in Chrome.
  3. Turn on Developer mode.
  4. Select Load unpacked and choose the project’s dist folder.
  5. Click the extension icon to test the popup. After changing files, rebuild the project and reload the extension.

Use the extension’s inspection tools to check for errors. Popup errors can be inspected from the extension card on the Extensions page, while service worker and content script errors appear in their respective contexts.

Common Development Tips

  • Keep permissions narrow. Extra permissions can reduce user trust and may complicate publishing.
  • Package all executable code. Do not load JavaScript from a remote server at runtime.
  • Use messaging thoughtfully. Keep communication between the popup, content scripts, and service worker explicit and validate messages.
  • Plan for the popup to close. A popup may disappear when the user clicks elsewhere, so save important state rather than relying on in-memory values.
  • Test the production build. Development servers and built extension pages can behave differently.

Conclusion

React is a practical choice for building the user interface of a Chrome extension, especially when the extension has interactive screens or reusable components. Start with a small popup, configure the build to produce a valid Manifest V3 package, and add Chrome APIs only as needed. With careful permission choices and thorough testing, a React-based extension can provide a smooth, maintainable experience for Chrome users.

 

6 Essential Tips for Developing Chrome Extensions with React

  1. Use Manifest V3 for new Chrome extensions.
  2. Build the popup and options page with React.
  3. Keep permissions minimal in the manifest.
  4. Use content scripts to interact with web pages.
  5. Store extension data with Chrome Storage APIs.
  6. Test changes in Chrome’s Extensions page.

Use Manifest V3 for new Chrome extensions.

For new Chrome extensions built with React, use Manifest V3, Chrome’s current extension platform. It defines how your extension handles permissions, background tasks, and communication between components, helping you build with modern security requirements in mind. Set `”manifest_version”: 3` in your `manifest.json`, request only the permissions your extension needs, and package your JavaScript with the extension rather than loading it remotely.

Build the popup and options page with React.

Build your Chrome extension’s popup and options page with React to create responsive, easy-to-maintain interfaces from reusable components. The popup is ideal for quick actions users can access from the toolbar, while the options page gives them room to manage preferences and settings. Keep each interface focused, and remember that both pages run as extension pages, so they can use Chrome extension APIs—such as storage—when the required permissions are included in your manifest.

Keep permissions minimal in the manifest.

Keep permissions in your Chrome extension’s manifest to the minimum necessary. Each permission can affect user trust and may trigger additional warnings, so request access only for features your extension actually uses. When possible, prefer optional permissions that users can grant when needed, and explain clearly why the access is required. This helps protect users’ privacy and makes your React extension easier to understand and use.

Use content scripts to interact with web pages.

Use content scripts when your Chrome extension needs to interact with a web page—for example, to read selected text, add a button, or update page content. A content script can access the page’s DOM, while React can power any interface you inject. Declare the script and limit its site access in your Manifest V3 configuration, and use message passing to communicate with your extension’s service worker when you need privileged Chrome API features. Test on the sites you support, since permissions and page structures can vary.

Store extension data with Chrome Storage APIs.

Use Chrome’s Storage APIs to save extension data that needs to persist between sessions, such as user preferences, settings, or notes. Unlike a React component’s state, stored values remain available after the popup closes or Chrome restarts. The `chrome.storage.local` area is useful for data kept on the user’s device, while `chrome.storage.sync` can sync supported settings across signed-in Chrome browsers. Request the `”storage”` permission in your extension’s manifest, and use the asynchronous API to read and write data—for example, `await chrome.storage.local.set({ theme: “dark” })`.

Test changes in Chrome’s Extensions page.

Test your React Chrome extension directly from Chrome’s Extensions page to catch issues early. Open chrome://extensions, turn on Developer mode, and select Load unpacked to add your built extension folder. After making changes, rebuild the project and click the extension’s reload button before testing again. Check the extension’s error messages and inspect its popup or service worker to troubleshoot problems.

About the Author

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit exceeded. Please complete the captcha once again.

You may also like these