Note: This blog was originally published on 7th October 2021 and updated on 14th March 2023.
Quick Summary: In this post, we will guide you seamlessly through the process of creating a Chrome extension with reactjs. By the end of this guide, you will be able to build your own extension functionality. So, without further ado, let’s get started.
What are the Extensions?
Small software programs that personalize the browsing experience, giving users the freedom to tailor the behavior and Chrome functionality keeping in mind the needs of the individual. Extensions are developed on different web technologies, including CSS, JS, and HTML. The purpose of having an extension is to make everything easy to understand. There are multiple components with different ranges of functionality in a single extension.
Recommended Read: 15+ Top React Libraries to Try
Key Takeaways
- Build components that respond to user input using React.js.
- Test your extension thoroughly using Jest, Enzyme, and Puppeteer.
- Publish your extension to the Chrome Web Store and follow the developer guidelines.
- Set up a React.js environment in your Chrome Extension project using tools like create-react-app or react-scripts.
How to Create React App?
In this step, we will be starting from a TypeScript React project created with the create-react-app CLI command.
npx create-react-app my-app --template typescript
Update the Manifest.json File
Now, if we are trying to create our extension work seamlessly, without any interruption, we will have to update the manifest.json file in the /public folder.
{
"name": "Hello Extensions",
"description": "Base Level Extension",
"version": "1.0",
"manifest_version": 2,
"browser_action": {
"default_popup": "index.html",
"default_title": "Open the popup"
},
"icons": {
"16": "logo192.png",
"48": "logo192.png",
"128": "logo192.png"
}
}
Default_popup will help us know how to find out the main HTML file.
Default_title helps us know what text the user will be shown when they hover on the extension icon.
Create React App, by default, embeds the small runtime script into index.html during the production build. Further, it minimizes the number of HTTP requests. There is a high possibility that you are going to witness console errors related to CSP. Besides, you can even turn off the embedding behavior. For that, all you need to do is set the inline_runtime_chunk flag to false. Also, you can add inline_runtime_chunk to your .env file or even add it before the build script.
INLINE_RUNTIME_CHUNK=false
Alternatively, you can try adding content_security_policy to the manifest.json file.
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
Once the manifest.json file is updated, it is time to run the yarn run build script. And, once that is finished, a new build folder is created at the root of the project.
After that, we just need to inform Chrome how and where to find the new extension. For that, we need to type in the Chrome Tab the following for opening the extension menu:
chrome://extensions/
Now, we will be selecting the /build folder of the project.
(Once you have updated/saved the code, click on Update to update all the extensions used.)
Check out the difference between Reactjs, angularjs and vuejs.
Popup Width and Height Restrictions in Chrome extension with Reactjs
We have created the extension until this step, but it might not look as good as we want. Hence, we will have to set the height and width of the CSS properties in the index.css file. And then save, rebuild, and update.
For the width and height of the extensions, you need to make them 800px and 600px, respectively.
How to Retrieve the Active Tab’s URL?
For this, we will have to add permissions to the manifest.json file.
"permissions": [
"activeTab"
]
After that is done, we will add useEffect hook to the App.tsx file.
import React, { useEffect, useState } from 'react';
import logo from './logo.svg';
import './App.css';
export const App = () => {
const [url, setUrl] = useState('');
/**
* Get current URL
*/
useEffect(() => {
const queryInfo = {active: true, lastFocusedWindow: true};
chrome.tabs && chrome.tabs.query(queryInfo, tabs => {
const url = tabs[0].url;
setUrl(url);
});
}, []);
return (
URL:
{url}
);
};
Now, you can save, rebuild, and update the extension to achieve the final look we want.
DOM Content Manipulation (Content Scripts)
So, we need to use the Content Scripts to access the DOM of the page. So, what are the content scripts? Well, these are the files that run in the context of web pages. When the DOM is used, it helps read every detail about the web pages the browser visits. Besides, it can even make changes to them and even pass essential information to the parent extension.
However, we will not be able to access the content.js file directly. We need to use Message Passing for that.
- Add content.js file to manifest.json file
- Add optional_permissions to manifest.json file
"optional_permissions": [
""
]
Recommended Read: 15 Advantages of ReactJS for Application Development
Adding Content Script File to the Project
Now is the time to place the content script in the /public folder directly. However, we can’t really do that because we don’t have all the TypeScript features that we need.
So, for that, we need to place the content script to the /src/chrome/content.js
import { ChromeMessage, Sender } from "../types";
const messagesFromReactAppListener = (message: ChromeMessage, sender, response) => {
console.log('[content.js]. Message received', {
message,
sender,
})
if (
&