Chrome Extensions | Top-Level Overview

In my opinion, working on and coding Chrome Extensions is not the easiest thing in the world. There are a lot of new terms and APIs to know about and things to keep in mind.

You have to learn about content scripts, the manifest file, background scripts, permissions to ask for, active Tab, etc.

In this article, I will try to give you a very high-level overview of the important concepts I’ve learned from building Chrome Extensions.

Top-level overview of how Chrome Extensions work

A chrome extension consists of a Manifest File, HTML, CSS, Javascript, and assets (icons, images).

You submit a zipped file through the Chrome Developer Dashboard. You have to explain what it does and why it uses certain permissions (that you specify in the manifest file). You then have to wait for the extension to get approved and then it is live in the Chrome Extension Store.

In a lot of extensions, you will have a popup HTML file that appears when you click on the extension. This HTML file can link to a javascript file through script src tags. This javascript file, linked from the HTML page, CANNOT access the DOM of the website you are on.

To access the DOM of the page you are on you need to use either a content script or using activeTab permissions. More on this shortly.

Let’s start by learning the types of Chrome extensions that exist.

Types of Chrome Extensions

There are 3 types of Chrome Extensions.

  1. Page Action Extensions
  2. Browser Action Extensions
  3. Extensions that just run in the background

Page Action Extensions

Page action extensions are only available on certain pages that the developer chooses.

For example one of my extensions is to get information on a course on Udemy. So the extension is a page action extension that only works on Udemy. On udemy the icon lights up but when you are on any other website the icon is greyed out.

In the manifest file you would specify the page action like so:

"page_action": {
    "default_title": "title",
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  }

The icon is the icon that appears next to the address bar.

However, if you want to get the popup to show, you need to do this using background scripts and content scripts as I will explain in later in this article.

Browser Action Extensions

Browser action extensions are always accessible.

You would use Browser action extensions when the extensions can work on any page.

For example, my other chrome extension is to get course information on teachable courses. However, unlike Udemy, teachable courses can be on any domain. In this case, I cannot use a page action since a teachable course doesn’t have to be on …teachable.com…

In the manifest file you would specify the browser action like so:

"browser_action": {
    "default": "icon.png",
    "default_popup": "popup.html"
  }

Neither page action or browser

The other type of Chrome extension is neither browser actions or page actions. These run in the background (usually only when it’s required).

An example of this type of extension is a Chrome extension that is only a context menu.

A context menu is when you right-click in your browser and then you see the options (“copy”, “search google” , etc). You can make an extension that gives a brand new option. For example, an option for “define” and when you highlight a word it googles the definition in a new tab. This is an example of an extension that is neither page or browser action and instead it is just in the background.

An extension like in my above example would require the following in the manifest file.


permissions:["contextMenu"],
background: {
    "scripts":["background.js"],
    "persistent": false
}

You would need contextMenu permissions and have the background with persistent set to false which indicates it’s not running at all times and only when it’s used. Most of the time you will use persistent false.

Manifest File

Every Chrome Extension will have a manifest file. In this file, you specify things like

  • the icon for your extension
  • the permissions the extension needs (when you download an extension it will show you the permission an extension asks for so you can decide whether or not to install it)
  • what type of Chrome Extension it is
  • The title
  • A description

and more. To see everything that is required and optional please see the official documentation here.

Let’s talk more about the permissions you specify in the manifest file because this can cause a lot of frustration if you are new to developing Chrome Extensions.

For example, you might be making API calls and the code looks perfect but it’s not working. A likely reason is you did not specify the permissions in the manifest file. Or you might want to use the Chrome Storage API but it’s not working, the reason is you have to specify this in the manifest file.

So always keep in mind to check whether or not the API or anything you are using requires permissions in the manifest file.

Content and background script

Content scripts

Content Scripts are used to manipulate and read the dom of the page you are currently on (such as changing the font-size of everything on the page). This can’t be done through the javascript file linked by the popup HTML and it can’t be done by the background script as those scripts don’t have access to the content of the page you are on.

However, content Scripts don’t have access to a lot of the useful Chrome APIs. For example, if you want to make an API call you have to use a background script. So to get around this limitation, the background script and the content script communicate through messages.

Background Scripts, as I mentioned, have access to Chrome APIs such as being able to show the page action, knowing what tab you are on, making API calls, etc.

Let’s see how Content and background scripts work together.

Example 1.

Let’s take a page action extension. Say you want the popup HTML file to appear when you click on it. One way this can be done is by using a combination of the background script and the content scripts.

You will need a content script to specify when the extension should be clickable. You do this in the manifest file as so.

"content_scripts":[
    {
        "matches":["https://website.com/*"],
        "js":["content.js"]
    }
]

This means that the page action will only light up on any URL of “website.com” (thanks to the wildcard * at the end).

However, if you were to click on your extension it wouldn’t work. Because the Chrome API that tells the page action to show the popup is only accessible through a background script.

So now you need a background script specified in your manifest file like so:

background: {
    "scripts":["background.js"],
    "persistent": false
}

Finally, you communicate between the background and the content script through messages like so:

In the content script:

//content.js file

chrome.runtime.sendMessage({msg: "showPopup"});

In the background script:

//background.js

chrome.runtime.onMessage.addListener(function(request,sender,sendResponse){
    if(request.msg == "showPopup"){
        chrome.tabs.query({active:true, currentWindow:true},function(tabs){
            chrome.pageAction.show(tabs[0].id);
        })
    }
})

In the above code, the background script is listening to any messages from the content script. When it receives the “showPopup” message, it will tell the page action to work and show.

Before it’s all set and done, in the manifest file, you also have to ask for “tabs” permission since we are using it in the background script and ask for permission for the URL where the content script is ran


"permissions":[
    ..., 
    "tabs", 
    "https://website.com/*",
    ...
]

Now the page action would work.

Let’s take a look at another example:

If you need to execute an API call and show the results on the DOM of the page you are on. You would communicate to the background script via a message. The background script now runs some API call and then returns the message to the content script which can now update the DOM.

Examples of what type of chrome extension to use

To try and help you understand a bit more. I will give you a few more examples of which Chrome Extension to use in which cases.

Example 1. An extension that just shows your social media information.

This would be a simple browser action. It should always be accessible and when you click on it is just shows a popup.

Example 2. An extension where you can highlight words, using a context menu option save them in local storage, and display them in a popup.

This would also be a browser action extension that uses background scripts. The background script is needed to access the chrome extension APIs for local storage and as well as to use the contextMenu API. The browser action is needed to show the popup displaying the saved words.

Example 3. An extension that changes the font styles in twitter

This would be a page action extension because it should only work on Twitter.

This extension would also require either activeTab permissions (explained later in this article) or content Scripts in order to access the DOM of the website.

activeTab permissions

A helpful permission I haven’t discussed yet but that I have used in my Chrome extensions is activeTab permissions

The way I like to think about activeTab is like a combination of the background and content scripts.

activeTab permissions gives you permissions to get access to the Tab you are on and also lets you manipulate the DOM of the page you are on via chrome.tabs.executeScript.

You specify activeTab in the permissions like this:

"permissions": ["activeTab"],

An example of how I’ve used activeTab permissions is in a browser action.

In a popup.js file (javascript linked through the popup.html), I use a feature of activeTab chrome.tabs.executeScript to run some javascript on the DOM of a page and get the information I need and then present that information back in the popup.html.

Debugging

Finally, something you will need to do, debugging.

Please note when you update the HTML and javascript of the popup.html or popup.js you don’t need to refresh the extension via chrome://extensions/. But if you make any changes in the background or content scripts you will.

To inspect the console for the popup.js you need to right click your extension and click “inspect popup”.

For content scripts, simply go to your regular console.

Otherwise, for the other javascript (background scripts) go to chrome://extensions/ and you should see `Inspect views background page.


These are some things I wished I knew from the beginning of how the Chrome extension ecosystem fits together.

It will still definitely take a while for everything to make sense, so my recommendation is by thinking about what kind of extension it should be first (page action , or browser action , or neither). From there, google everything as needed and use the Chrome Extension documentation to see all the available APIs and permissions you need when coding a Chrome extension.