Custom Google Chrome Extensions

Custom Google Chrome Extensions

This post was translated using the DeepL translator, so I apologize for any incomprehensibility. In this article you can read more about my decision.

Have you ever thought of a feature that would be useful as an extension to your browser, but didn't know where to start? This guide is for you. We'll show you how to create an extension that allows the user to generate arbitrarily large images from an external API. Then, at the end of the article, you'll find some useful resources on where to go if you'd like to do more extension creation.

The basis is the manifesto

The most important extension file is manifest.json it is the entry point from which the browser knows the name of the extension, the version and also what files to load and what features or rights the extension uses. A very basic manifest.json should look something like this:

2  "name": "Image Generator",
3  "version": "1.0.0",
4  "manifest_version": 2,
5  "description": "Generate an image,
7  "icons": {
8    "16": "icons/icon-16.png",
9    "32": "icons/icon-32.png",
10    "48": "icons/icon-48.png",
11    "128": "icons/icon-128.png"
12  }

I'll stop at just two properties, namely manifest_version. This value specifies not only the version, but also the available features and expected properties of the file. At the moment, it is more appropriate to use version 2, although Google already officially supports version 3 as well. However, you will usually come across a version 2 manifest solution when solving more complex problems, and some databases still do not support version 3 extensions - for example Microsoft.

The second value is the icons field, the basic set of sizes should be 16, 32, 48 and 128 pixels. However, chrome.browserAction also uses 24px. You may also encounter values of 19 and 38, these should be obsolete at this point and are not used see Stack Overflow.

Viewing the extension window

This would give us a defined extension, but if we loaded it into the browser, nothing would happen. To do this, we need to add another value to the manifest.json file:

2  "browser_action": {
3    "default_popup": "popup.html" .
4  }

The browser_action value defines the actions that should be available in the main menu of the browser, i.e. through the extension icon. Values for icon, help, badge and popup can be defined here. In this tutorial, we'll make do with just the popup. However, if you are interested in other options, see for example the Chrome Developers website.

The popup.html file should be located in the same folder as manifest.json, for simplicity I won't structure the directories in any way, however it is good practice to split the different parts of the extension into their own folders.

The contents of the popup.html file is a standard HTML page, which may contain references to CSS stylesheets or custom scripts.

1<!DOCTYPE html>
2<html lang="en">
3  <head>
4    <meta charset="UTF-8">
5    <meta http-equiv="X-UA-Compatible" content="IE=edge">
6    <meta name="viewport" content="width=device-width, initial-scale=1.0">
7    <title>My first extension</title>
8    <link rel="stylesheet" href="style.css">
9  </head>
10  <body>
11    <h1>Image generator</h1>
12    <p>Generate any size image</p>
13    <input type="text" id="imageSize" placeholder="Size, e.g. 360x200">
14    <img id="imagePreview" src="" alt="360x200">
15    <input id="imageLink" type="text">
16  </body>
17  <script src="popup.js"></script>

In this case we load two more external files - style.css and popup.js. The first one should contain the design of our extension and I will not mention it further in this tutorial. The second file then contains all the important functions. Besides the files, we will also display the title, i.e. the name, text, two inputs and an image in our extension.

Load extension in browser

Before we start adding functions to our extension, let's test if it will load in the browser. I'm showing the procedures for the two most common browsers, however if you use a browser with a chromium core, the procedure will be the same.

Google Chrome

  1. Type chrome://extensions/ in the browser address to open the extension settings
  2. In the top right corner, first switch to developer mode (Developer mode)
  3. A panel with several options will appear: Load unpacked (Load unpacked), Pack extension (Pack extension) and Update (Update). Select the Load unpacked option.
  4. In the window that opens, find the extension folder where the manifest.json file is located and click open.
  5. The extension should appear in the list of extensions.

Microsoft Edge

  1. Type edge://extensions/ in the browser address to open the extension settings
  2. In the left panel, at the very bottom, there is a toggle for developer mode (Developer mode), turn it on
  3. In the extensions panel on the right, there are several options to load unpacked (Load unpacked), Pack extension (Pack extension) and Update (Update). Select the Load unpacked (Load unpacked) option.
  4. In the window that opens, find the extension folder where the manifest.json file is located and click Open
  5. The extension should appear in the list of extensions.

If the extension is displayed in the extension list, it should also be displayed in the browser taskbar. Clicking on the extension icon, the popup we defined in the previous step should appear. This should successfully load the extension in the browser.


If everything went well, it's time to revive the extension. So let's open the popup.js file and add some functions to it.

Custom image dimensions

The first input in the view should be used to enter the dimensions of the image, the view should then ideally update when the enter key is pressed. There are many ways to achieve this, I chose the onkeypress event in this tutorial. However, extensions do not allow adding functions to events in an HTML page, so we cannot use the onkeypress attribute. Instead, the event needs to be registered in a JavaScript file, as follows:

1const imageSizeInput = document.getElementById('imageSize')
2imageSizeInput.addEventListener('keypress', updateImageSize)

Using getElementById we get the DOM element from the HTML page and then through the addEventListener function we add the keypress event function, which should be called whenever a key is pressed. To prevent the preview from updating with every keystroke, for example, we can use the following condition if (event.key === 'Enter') to ensure that the function only runs if the user presses the enter key.

1function updateImageSize (event) {
2  if (event.key === 'Enter') {
3    resizeImage(
4  }

Before we start defining the resizeImage function, we need to find two more elements in the document, the image and the input that will contain the reference to the image. So we add the following two lines to the beginning of the file:

1const imagePreview = document.getElementById('imagePreview')
2const imageLinkInput = document.getElementById('imageLink')

Now there is nothing stopping us from defining the resizeImage function, which will modify the image source and replace the input value with a reference to the image.

1function resizeImage (size) {
2  imagePreview.src = `${size}?text=${size}&color=4ddd9a&text-color=145b3a`
3  imagePreview.alt = size
4  imageLinkInput.value = imagePreview.src

So the interaction would be ready, but in order for the changes to be reflected in the browser extension, the extension needs to be updated. To do this, open the page with extensions - chrome://extensions/ or edge://extensions/ and click the Load again (Reload) button for our extension. The extension should then load the changes and after clicking on the icon in the browser bar, adjusting the size in the first input and pressing enter, the image should be updated with the new one.

Appearance of the extension

As I wrote at the beginning, the goal of this tutorial is not to design the extension, but rather to illustrate the basic process and give you a hint on how to get started. For this reason, I will not describe what the extension might look like, but instead point out a few things. The extension popup window should be no smaller than 25x25 and no larger than 800x600 pixels. In general, any CSS that is supported by browsers can be used.

Additional resources

Congratulations on the successful creation of your extension for Google Chrome and Microsoft Edge. If you are interested in the whole process and would like to learn more, I recommend visiting the following sites Chrome Developer and Microsoft Edge documentation.