Creating extensions for Google Chrome with React and Typescript
Tags: react, tailwindcss, extensions, typescript
Published: 2024-01-02 17:59:00

Recently browsing the internet I came across the subject of **creating extensions for Google Chrome**, I became interested so I decided to study a little about it.

And what is the best way to study in this tech field? **Getting your hands dirty.**

I started reading some articles, posts on stackoverflow and so on. But I came across countless ways to do the same thing, and many of them were **super complicated.**

But does it really need to be so complex?

Why not use tools that make this work easier? That's when I came across a post explaining the use of this solution with React + Typescript + Webpack.

Well, it seems simple, but not so much lol. That's why I decided to create this brief content as a way of learning and also to make available some things that I didn't find out there but rather get my hands dirty.

I also made this content available on Github if you want to use it as a boilerplate or even evolve it for the community.

[https://github.com/lucaxsilveira/react-typescript-chrome-extension](https://github.com/lucaxsilveira/react-typescript-chrome-extension)

Main technologies used in this project:

React

- Typescript
- Webpack
- Tailwindcss
- Eslint + prettier + editorconfig

So, an extension is basically built inside a popup, which is defined in the manifest file defined by Google (manifest v3).

![manifest v3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r8odzb559u3c7d19i7ti.png)

Some important points in this file:

- **actions** - basically what will be the html responsible for displaying the popup when opening the extension
- **permissions** - permissions your extension can have
- **background** - file related to commands that will be sent to the background of your extension
- **content_scripts** - multiple files that can be added and run within the window in question

For a better definition of all possible keys and values, you can find it here [https://developer.chrome.com/docs/extensions/reference/manifest](https://developer.chrome.com/docs/extensions/reference/manifest)

Talking a little more about **content_scripts**, these files will be **added to the page** in question that the user is browsing and not within the popup.html that is opened when the extension is clicked. For example, we can have the following behavior:

The user clicks on a button, in this case **Open content page**, and from then on you can, based on a condition / or not, render something within the page.

![chrome browser content script](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x1rz8petabhhay015v6c.png)

This opens up a huge range of interaction possibilities for the page.

But cool, how do we do this via code? Simple, rendering another React application within **contentScript.js** itself

![rendering contentScript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pdv0sxxunzbmpd168fmn.png)

This file is **automatically injected** by the browser, so be very careful with what you do inside it, generally adding some viewing rule is necessary.

![visualization rule for content_scripts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/72mjimp1lp13jw2hitl6.png)

As we see in this code above, it will only be displayed if a message is received, this is where the magic comes in.

We can trigger this directly from popup.html

![trigger event for the content_script](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nwbph3mp2rgz2gh5vfy1.png)

Clicking on the button then **triggers a message**, this message is "heard" by content_scripts, thus displaying the div on the page for the user.

With these listeners, an infinite number of business rules can be created. I brought a simpler case to show that it is possible to have visualization directly on the page in a simple way and with the best technologies on the market.

**Trigger example**

```
chrome.tabs.sendMessage(tab.id, {
  value: "openPopup",
});
```

**Example of listening**

```
chrome.runtime.onMessage.addListener((message) => {
  if (message.value === "openPopup") {
      
  }
});
```

Well, that's it, see you soon!