plasmo

How to Inject a React Component Onto a Web Page Using a Chrome Extension

We'll walk through all of the steps required to make injecting React components a piece of cake

Stefan Aleksic
Stefan AleksicSeptember 22, 2022
cover image for blog

When you first start building moderately complex browser extensions, the first thing that you'll likely try to do is to inject some UI onto a page, whether that's adding a new button on top of Gmail or an overlay that shows some helpful information on the top right corner of every page.

We'll be using the Plasmo Framework for this walkthrough as it's the easiest way to build React-based browser extensions and has some nice abstractions that make a lot of this injection stuff much easier to reason about. (Disclaimer, I'm one of the creators!)

If you're unfamiliar with our Content Scripts UI, take 5 minutes and read through this blog post which should get you up to speed with the concepts described here.

Injecting a React Component

There are two ways we can inject a React component onto the page. We can either inject it as a child of another HTML element or think of it as an overlay and just overlay it on top of another element on the page.

It's up to you to decide what makes more sense for your use case. Do you want the element to exist within the other elements, or do you want it simply to float on top of them?

If it's unclear which one is right for you, it'll likely make more sense as you keep reading, as we'll be going through both of them in more depth below!

Inline

For a sneak peek of what we'll be building, we have a Nyan cat gif injected into the Gmail compose window!



Step 1: Create a Plasmo project

1pnpm create plasmo

Once you cd into the directory that Plasmo created, you can do pnpm dev, and drag and drop the built folder into your Chrome extensions page. Now you'll get instant live-reloading as you develop your extension!

Step 2: Rename the popup.tsx file to content.tsx

1mv popup.tsx content.tsx

The generated default popup file exports a simple React component that we can use for our content script instead!

Step 3: Add a config declaration in content.tsx to run the content script whenever the user is on Gmail

1import type { PlasmoContentScript } from "plasmo"
2
3export const config: PlasmoContentScript = {
4  matches: ["https://mail.google.com/*"]
5}

We must ensure that Plasmo only injects this React component when the user is on Gmail.

Step 4: Add a config declaration in content.tsx to tell Plasmo where to mount your component

1export const getInlineAnchor: PlasmoGetInlineAnchor = () =>
2  document.querySelector("h2 > div.aYF > span")

You need to let getInlineAnchor know what sibling you want your React component to have. The question you need to answer here is, "which HTML element do I want my React component to be next to?"

By default, Plasmo will insert your React component before the sibling you specify, but you can change this functionality by exporting a mountShadowHost function and specifying your functionality inside.

Step 5: Update the exported React component to return a Nyan Cat gif

1...<react component>
2
3  return (
4    <div>
5      <img src="https://c.tenor.com/-AyTtMgs2mMAAAAi/nyan-cat-nyan.gif" />
6    </div>
7  )
8
9

If everything worked according to plan, you should be able to see a Nyan Cat gif when opening up the compose window in Gmail!

Overlay

If you'd like absolute positioning with your React component floating above the rest of the HTML elements on a page, the overlay method will do the trick!

Here, we have a Nyan Cat gif overlayed on the left-hand side of the pricing section on the Plasmo landing page!

Step 1: Create a Plasmo project

1pnpm create plasmo

Once you cd into the directory that Plasmo created, you can do pnpm dev, and drag and drop the built folder into your Chrome extensions page. Now you'll get instant live-reloading as you develop your extension!

Step 2: Rename the popup.tsx file to content.tsx

1mv popup.tsx content.tsx

The generated default popup file exports a simple React component that we can use for our content script instead!

Step 3: Add a config declaration to specify you want this content script to execute on plasmo.com

1export const config: PlasmoContentScript = {
2	  matches: ["https://www.plasmo.com/*"]
3}

Step 4: Add a getOverlayAnchor function to anchor on a div

1export const getOverlayAnchor: PlasmoGetOverlayAnchor = async () =>
2	  document.querySelector<HTMLElement>("#pricing")

Here, we return a query selector where it'll find a DOM element with the pricing ID. This is where Plasmo will overlay our React component on top.

Step 5: Update the exported React component to return a Nyan Cat gif

1...<react component>
2
3  return (
4    <div>
5      <img src="https://c.tenor.com/-AyTtMgs2mMAAAAi/nyan-cat-nyan.gif" />
6    </div>
7  )

We hope this guide has helped you on your journey of building excellent browser extensions. We're working hard to make this space more welcoming and abstracting away many significant issues in browser extension development. If you'd like to keep up to date with the latest Plasmo offers, follow us on Twitter and subscribe to our newsletter!

Back to Blog


Thanks for reading! We're Plasmo, a company on a mission to improve browser extension development for everyone. If you're a company looking to level up your browser extension, reach out, or sign up for Itero to get started.