How to Create Your Own Firefox Add-on with React

Žan Ožbot
Apr 11 · 7 min read

Either you want to explore new ways to bring traffic to your web application or just learn a new skill you came to the right place.

But what exactly is an extension or an add-on? Mozilla says it best.

Extensions are like apps for Firefox. They add features to Firefox to make browsing faster, safer, or just plain fun.

We’ll take a look at how to create a simple Firefox extension using React and go through the submission process together. Hint: it's simpler than you think.

You can find the source code for this project on my GitHub.

Firefox Add-on created with React.

Creating a simple React application

We’ll create a simple generator that enables users to create universally unique identifiers or UUIDs. UUID is a 128-bit piece of data displayed in a form of 32 hexadecimal digits, e.g., 3adee25a-eb20–48ca-9106–84820e108b20.
There are a few different versions of UUIDs. It all depends on how they are generated but for simplicity's sake, we’re only going to implement the one that generates UUIDs using random numbers — version 4.

Firefox Add-on we’ll create.

The best way to create a new React application is by running npx create-react-app which sets up the development environment for us. The only prerequisite you need is to have Node >= 10.16 and npm >= 5.6 installed on your machine. We’ll use React in combination with Typescript and npm therefore, we need to add the --template typescript and --use-npm flags.

npx create-react-app uuid-extension --template typescript --use-npm

We’re going to install two libraries which will help us speed up the development process. The first one being Material UI and the second one uuid which also requires its types to be installed as a development dependency.

npm install @material-ui/core uuid
npm install --save-dev @types/uuid

I’m assuming you already know the basics of React so I won’t bore you with the details on how the code we’re going to write works. That said, let’s get started.

First, let’s clean the project a little bit. We can safely delete the contents of the App.tsx‘s return function and remove logo.svg,App.test.tsx, and App.css from the src folder. Let’s also remove favicon.ico, logo192.png, logo512.png, and robots.txt from the public folder since we won’t be needing any of them. The cleaned App.tsx should look like this.

//App.tsx
function App() {
return (
<></>
);
}
export default App;

In the next step, we’re going to add the extension’s functionalities. It’s not really preferable to stick everything into App.tsx but since this is a really simple extension we can afford to do that.

That’s all the code we need to get this extension up and running. So let’s break it down and see what we actually did. I’ll be referencing the above code a lot so to make things easier I’ll put the line numbers inside square brackets like so [4–9], meaning from lines 4 to 9.

  • [1–5] adding all of the necessary imports.
  • [8] getting the preferred color scheme from the user which we’ll use to change the extension’s theme.
  • [12–30] creating a Material UI theme object which will according to the user’s settings generate either a light or dark color palette. Additionally, we’re overriding some typography settings.
  • [32–34] the function responsible for generating new UUIDs and updating the state.
  • [37,58] if we want to use the out-of-the-box theming functionalities Material UI provides us with we have to wrap everything inside ThemeProvider.
  • [38] CssBaseline resets the CSS to a consistent baseline so you can expect the elements to look the same across all browsers.
  • [39–57] creating a simple layout using the grid, center its items, and space them evenly across the y-axis.
  • [46] I’ve found user-select: all CSS style to be a simple way to replace the copy-to-clipboard functionality. It basically selects the whole text, in our case the generated UUID, when a user clicks on it.

What makes it an extension?

We’ll have to do three things to turn our React application into a Firefox extension. First, we have to create a logo for our extension. Once we’re happy with the design we have to export a 48px, 96px, and 128px version of it. We place the first two inside the public folder. Let’s name them something generic like logo48.png and logo96.png. The 128px version will be used in the submission process.

UUID Generator’s logo

Secondly, we have to update the contents of manifest.json which is located in the public folder. There are multiple types of manifests and the one we’re updating tells the browser about the web application and how to behave when installed on a user’s device. Since we are developing an extension we have to change its contents.

{
"name": "UUID Generator",
"description": "Generate universally unique identifiers fast.",
"version": "1.0.0",
"manifest_version": 2,
"homepage_url": "https://github.com/zanozbot/uuid-generator",
"browser_action": {
"default_popup": "index.html",
"default_title": "UUID Generator",
"default_icon": {
"48": "logo48.png",
"96": "logo96.png"
}
},
"icons": {
"48": "logo48.png",
"96": "logo96.png"
}
}

Using the modified manifest we tell Firefox some basic information about the extension and we can also specify our extension’s functionalities such as background scripts, content scripts, and browser actions. As you can tell from the above manifest.json we’re using the browser action which adds a button to Firefox’s toolbar and opens a popup when clicked.

The final thing we have to do is to create a .env file at the root of the project and paste the following line INLINE_RUNTIME_CHUNK=false inside. When running npm run build the React compiler will pick this up and won't insert the runtime script into index.html but rather import it as usual. This is in my opinion the easiest way to add development environment variables to React projects. Read more about adding development environment variables in .env.

We’re now ready to build the extension for production.

npm run build

Testing it out

To test our extension we have to open the Firefox Debugging tool. We do that by typing about:debugging in the Firefox URL bar. Next, we click on the This Firefox tab which provides information about the extensions and running workers. Our focus will be on the top of the page, more specifically on the Temporary Extensions panel.

Click on Load Temporary Add-on… which should open a file picker. Navigate to the build folder of the extension, select the index.html and press Open.

Loading our extension temporarily.

This enables us to preview the extension and if we’re satisfied with how it looks and functions we can proceed to the final step which is submitting it to the Add-on Developer Hub.

Submitting it to Add-on Developer Hub

Navigate to Add-on Developer Hub and click on Submit or manage extensions. If you are already logged in the provided link should take you to your console where you can simply click on Submit a new Add-on.

Submitting a new extension.

After that, we’re asked to decide how we’re going to distribute the extension either on our own or on the Firefox Add-ons Manager. We’ll choose the latter.

Choosing a way to distribute the extension.

Next, we’re finally asked to upload the extension. But before we can do that we have to compress all of the contents of the build folder into a ZIP file. After that, we can click on Select a file… and open the freshly compressed file.

Uploading the extension.

In the next step, we’re asked to review the source code submission policy and attach the source code if needed. Since we’ve developed an extension in React and React does minify and generate some additional code we also have to compress and upload the source code.
Don’t forget to include instructions on how to build your extension in the README.md file to avoid unnecessary rejections.

Uploading the extension’s source code.

Lastly, we have to describe the extension we’ve just uploaded. Some information will already be prefilled from manifest.json we created earlier. After filling in all of the required fields, we’re finally ready to submit the extension by clicking on the Submit version.

Submitting our first version of the extension.

That’s it. The extension should be available on Firefox Add-ons Manager in no time. Since we want to increase the chances of it being discovered we’ll also provide some additional information that wasn’t available in the previous steps such as images and tags. We can do that by clicking on Manage Listing.

Adding additional information about the extension.

After we’re happy with the results we can navigate to the submissions page and start refreshing it. The best part of the whole submission experience is that Add-on Developer Hub actually shows you when your extension is going to be reviewed.

The current position in the reviewing queue.

If you’d like to create an extension for Google Chrome check out Dik’s article on Creating your own Chrome Extensions with React is easier than you think.

Geek Culture

Proud to geek out.

Sign up for Geek Culture Hits

By Geek Culture

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Žan Ožbot

Written by

Full stack developer and tech enthusiast.

Geek Culture

A new tech publication by Start it up (https://medium.com/swlh).

Žan Ožbot

Written by

Full stack developer and tech enthusiast.

Geek Culture

A new tech publication by Start it up (https://medium.com/swlh).

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store