ReactJS WebExtensions

mrloop

Ewan McDougall

Posted on September 4, 2020

ReactJS WebExtensions

This post originally appeared on my personal blog.

I wanted to write a WebExtension for Firefox and Chrome in ReactJS, with little configuration in the simplest possible manner, using create-react-app and web-ext, I couldn't find any guides or instructions online so this is the setup I used. create-react-app is the recommended tool for creating new single page applications in React.

Lets create an app, first make sure you've got Node.js installed then:

npx create-react-app web-ext-react-hello
cd web-ext-react-hello
npm start
Enter fullscreen mode Exit fullscreen mode

We have a basic react app running. The next step is to bundle it as a web extension. For this we will use web-ext-react, the library I extracted from race-ext-react to help bundle react apps as web extensions.

yarn add -D web-ext web-ext-react
Enter fullscreen mode Exit fullscreen mode

A web extension can have multiple different javascripts, HTML and CSS for different parts. For example your web extension may have a sidebar or a popup, each with its own javascripts, HTML and CSS. As create-react-app is designed to output a single app and not multiple, we need to conditionally invoke different components of our single react app depending on the context, be it the sidebar, popup, content script or background script. In this case we'll add a browser action popup. The App component will be conditionally rendered if invoked from the browser action context.

src/index.js

if (document.isBrowserAction) {
  ReactDOM.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>,
    document.getElementById("root")
  )
}
Enter fullscreen mode Exit fullscreen mode

The extension needs a manifest.json, create extension/manifest.json and copy the logo to the extension directory cp public/logo192.png extension

extension/manifest.json

{

  "description": "Bundle ReactJS as web extension",
  "manifest_version": 2,
  "name": "web-ext-react-hello",
  "version": "1.0",
  "homepage_url": "https://github.com/mrloop/web-ext-react-hello",
  "icons": {
    "192": "logo192.png"
  },

  "browser_action": {
    "default_icon": "logo192.png",
    "default_title": "Hello WebExt",
    "default_popup": "popup.html"
  }
}
Enter fullscreen mode Exit fullscreen mode

This manifest declares a browser action with the react logo. This will appear in the browser toolbar when the extension is run. Clicking the icon and you'll see the popup running the App component.

To start the extension scripts can be added to package.json

package.json

"scripts": {
  "start:firefox": "web-ext-react run | xargs -L1 web-ext run -u http://www.example.org/ -s",
  "start:chrome": "web-ext-react run | xargs -L1 web-ext run -u http://www.example.org/ -t chromium -s",
}
Enter fullscreen mode Exit fullscreen mode

Tweak the styling, add padding and changing min-height.

src/App.css

.App-header {
  padding: 1em;
  background-color: #282c34;
  min-height: 200px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}
Enter fullscreen mode Exit fullscreen mode

Now run yarn start:firefox

Alt Text

We now have the default create-react-app running as a web extension! Try editing the app and live reload still works.

For complete source code please visit https://github.com/mrloop/web-ext-react-hello

💖 💪 🙅 🚩
mrloop
Ewan McDougall

Posted on September 4, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

ReactJS WebExtensions
javascript ReactJS WebExtensions

September 4, 2020