How to build a chrome plugin
Tags: codenewbie, javascript
Published: 2020-09-08 22:42:56

Chrome plugins are fun and can be a useful and personalised way to start your day. 

Best part is the are actually relatively simple to do. 

All you need is html, css, and js.

## Basic Setup
The basic setup is so basic I found myself staring at my computer saying what? 

Create manifest.json file [chrome's documentation](https://developer.chrome.com/extensions/manifest) is actually great and in depth if you want to learn more but for this plug in the manifest will be bare bones:
```
{
  "manifest_version": 2,
  "name": "Chrome plugin template Devto",
  "description": "Chrome plugin template Devto",
  "version": "1",
  "author": "Jenny Judova",
  "browser_action": {
    "default_title": "Fun with Flags"
  },
  "chrome_url_overrides": {
    "newtab": "newtab.html"
  },
  "permissions": [
    "activeTab",
    "storage"
  ]
}
```
  
## Print Hello World
Now let's do the thing and print 'Hello World.'

In the manifest.json chrome_url_overrides we stated that the new tab override html file is called newtab.html so lets create that file. 

newtab.html
```
<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
</head>

<body>
  <h1>Hello World!</h1>
</body>

</html>
``` 

This is great but how do we check if it worked? We can't really go to localhost for this. Instead, do this: 
1 - go to chrome://extensions/
2 - make sure that the developer mode toggle is on
3 - click on load unpacked button
4 - choose the folder with your project
5 - click ‘select’ 
6 - open new tab

![gif showing the step-by-step process of uploading the plugin to chrome](https://dev-to-uploads.s3.amazonaws.com/i/ldytbysdsf27f03fl3et.gif)
![Hello World displayed in a new tab](https://dev-to-uploads.s3.amazonaws.com/i/h3zp3yfiq9yb6f9xsrjd.png)

BOOM! 

Now let's make this extension do something like show flags and countries. Don't judge Fun with Flags I chose the flag API as it does not require a token. 

## How to make an API call 

Let's create a file called newtab.js and link it up in newtab.html by adding 

```
<script type="text/javascript" src="newtab.js"></script>
```

Just before the closing the body tag. Let's do a sanity check and in newtab.js add

```
function init() {

  console.log('HI')

}

window.addEventListener('DOMContentLoaded', init)
```

A simple .fetch should do the trick for the API call. Like so:

```
  function getAllFlags() {
    fetch('https://restcountries.eu/rest/v2/all?fields=name;flag;region;nativeName;')
      .then(response => response.json())
      .then(response => {
        flags = response
        chrome.storage.local.set({ data: flags });
      })
      .catch(err => console.log(err))
```

We have the information about flags now lets display them in the UI by adding a function to display them and some css, for this it's worth looking at the [project's github](https://github.com/JennyJudova/chrome-plugin-devto).

## How to use chrome.storage.local
The way the extension works at the moment is that every time you open a new tab a new api call takes place. Considering most of us open a dozen tabs every hour it might be more efficient to store the request response in **chrome.storage.local** and to check if it has data before running the call to the api.

To achieve this we have to use 
**chrome.storage.local.set** and **chrome.storage.local.get**

Also make sure to avoid this **common pitfall** - check that your manifest.json has
```
  "permissions": [
    "storage"
  ]
```


To save something to local storage lets add this line to the fetch request 

```chrome.storage.local.set({ data: flags });```

so the whole thing will look like:

```
fetch('https://restcountries.eu/rest/v2/all?fields=name;flag;region;nativeName;')
        .then(response => response.json())
        .then(response => {
          console.log('empty')
          flags = response
          chrome.storage.local.set({ data: flags });
        })
        .catch(err => console.log(err))
```

Lets add a function that will check local storage.

```
  function checkLocalStorage() {
    chrome.storage.local.get('data', function (result) {
      result.data == undefined ? isLocalStorageFull = false : isLocalStorageFull = true
      getAllFlags(isLocalStorageFull)
    });
  }
```

Let's also update the getAllFlags function to: 

```
  function getAllFlags(isLocalStorageFull) {
    if (isLocalStorageFull) {
      chrome.storage.local.get('data', function (result) {
        flags = result.data
        displayFlags(flags)
      })
    } else {
      fetch('https://restcountries.eu/rest/v2/all?fields=name;flag;region;nativeName;')
        .then(response => response.json())
        .then(response => {
          flags = response
          chrome.storage.local.set({ data: flags });
          displayFlags(flags)
        })
        .catch(err => console.log(err))
    }
  }
```

Essentially this is our plug in done. Feel free to add your own css or copy paste from the finished app [here](https://github.com/JennyJudova/chrome-plugin-devto). 

This is what we end up with. 

![Fun with Flags plug in that has the title and underneath it a grid showing flags and their countries](https://dev-to-uploads.s3.amazonaws.com/i/0ne8b0ndc7iztp3y70xu.png)