Create Chrome Extension in React
Louis Bayard
Posted on March 19, 2020
When I moved to Edge weeks ago, I found there's no built-in strong password generator in Edge. Then I decide write one for it.
Most of the extensions on marketplace are write many years ago, and they were written in raw HTML, CSS and JavaScript. But we have React and UI component libraries now, life should be easier.
The problem I soon found is there's almost no tutorial for a React extension anywhere. That's why I decide to share everything here.
- The source code is origin from my side project 10converters.com.
- Repo on Github strong password generator.
- Edge Extension Addons Store: Strong Password Generator.
Star the repo on Github or leave a review on Edge Addons Store are both welcome!
Features of the extension
It generates a 15 characters long password with lowercased letters, uppercased letters, numbers and symbols.
But it won't like Chrome built-in password manager, it doesn't:
- copy to clipboard automatically
- fill in the password/confirm field in web page
- manage/backup your password somewhere, not in cloud, not even do it locally
It does:
- keep everything running in client side, that means no server at all
- manual copy to clipboard
I tried to make it as simple as a one-day-job. Anyone who follows this tutorial could submit your own extension to Chrome Web Store or Microsoft Edge Extension Addons(what a long name) in a single day(but from my experience, Microsoft need 2-3 days to approve your submission).
Extension Basic
Before dive into the details, I want to explain a little the basic structure of an extension of 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:
manifest
manifest describes what's in the source package. It specified where browser could find background, content script, popup and option pages. As well as it describes permissions required by the extension.
background
A piece of code which is launched when the extension launched, and won't be terminated until extension removed or browser shutdown.
Background code has access to all chrome APIs, other parts are limited. But background doesn't have an UI and can not access DOM.
popup
The UI which is popped up while user click on 'browser action' which is your extension icon button right to the browser address bar.
Most extensions need a popup as entry.
options
It's an optional part of the extension. Not all extensions has 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
Content script is a piece of JavaScript which runs in a tab with specific URL. the URL pattern is defined in manifest.json. If the URL matched with which is specified in manifest.json, 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 content script.
So you should already have idea of what these parts are doing now.
Which parts involved in Strong Password Generator extension
Background, not in this tutorial, but there's an empty background.js in repo, just for future use.
Popup, yes. That's the focus of this article. I will show you how to write a Popup in React + Material.
Options, no.
Content script, no.
Start from scratch
Here're 5 steps to create an extension in React from scratch.
Step 1: create a react app
$npx create-react-app extension
This will create a regular react app. Everything else are growing from this seed app.
Step 2: Modify public/manifest.json
You've already had a public/manifest.json after CRA(create-react-app). Change the file as below:
{
"name": "Strong Password Generator",
"version": "1.0.0",
"manifest_version": 2,
"description": "Strong password generator",
"icons": {
"512": "logo512.png"
},
"browser_action": {
"default_icon": "logo512.png",
"default_popup": "popup.html"
}
}
Step 3: Create a build script(script/build.sh)
#!/bin/bash
build() {
echo 'building react'
rm -rf dist/*
export INLINE_RUNTIME_CHUNK=false
export GENERATE_SOURCEMAP=false
react-scripts build
mkdir -p dist
cp -r build/* dist
mv dist/index.html dist/popup.html
}
build
There're 2 things did in this script:
- build react app with some specific environment variables set
- renamed index.html into popup.html
INLINE_RUNTIME_CHUNK=false disabled webpack generating inline JavaScript in HTML. Normally webpack will put its own runtime into HTML inline script. But inline script is not allowed by browser extension.
Rename index.html into popup.html because it is required to be popup.html in manifest.json.
After create script/build.sh, don't forget add x permission:
chmod +x script/build.sh
Step 4: Modify package.json
modify scripts like below:
"scripts": {
"start": "react-scripts start",
"build": "./script/build.sh",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
Step 5: Build and load into Chrome(or Edge)
$npm run build
Then you will get a 'dist' directory. Load it as unpacked extension in Chrome or Edge. You would see:
The React extension is running.
To be continue
There're still pending issues for a serious extension, like:
- How to handle Options page? It's another page rather than Popup, but CRA created a SPA.
- Is there any performance issue to write extension in React?
- My content script is going to inject some UI component into host pages, can React be applied in this scenario?
And maybe some other topics not related to React too much but still important for a serious extension:
- How to obfuscate source code, especially background.js
- I'm going to introduce Firebase in my extension, any tips?
All the above will be discussed in the next post if someone interests into these questions. Leave a comment below if you have any other questions, suggestions, any feedback are welcome.
Posted on March 19, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.