Chromium Extension: Creation, Publication, Experience

In search of new sites for activities, I drew attention to the “widgets” of chrome, which I have been using for a long time, but never gave them any meaning. Immediately I wanted to try to implement something.

The idea was to create a task manager for the developer (and not only) that would be always at hand. It should display the actual tickets trello and jira , requests in gitlab , etc. These are the things that I usually searched for by typing keywords in the browser address bar, such as "jira PM-20".

Chrome extension

I knew for sure that extensions in browsers are normal html-pages, fed by js-scripts. But at the same time he had no idea how to create them. The first thing that gave me Google on this issue is  an article on medium , and not official documentation. It was even better, because This was a review article of the simplest widget from idea to publication.

The article gave me an idea that the development of the "widget" is not too tricky. I immediately started creating "hello world!".


It turned out that you need to create mainfest.json at the root of the project. It describes the extension: name, description, author, icons, permissions, etc. I did the first version without studying the documentation.

First manifest.json

Extensions allow you to run js-scripts in the background, which do something even when the user does not use them. I felt this functionality very superficially, just to understand how it can work. He just changed the title in the <h1> widget.

Of interest to me was the html page itself, which is shown when I click on the icon in the browser, it is called popup.html in my manifest.

This page, by the way, can be opened in a browser like any other site, only as a “protocol” there will be a chrome-extension,chrome-extension: //id- widget-in-webstore/popup.html . Thus, you can view the source code of any extension that you have installed.

It works in the same way as any website, except for a couple of possibilities, for example: following links only work with target = "_ blank" . There are also technical restrictions managed by the developer, such as the Content Security Policy or permissions to the browser functionality that are requested from the user.

Run extension

After creating a folder with manifest.json and popup.html inside, you can already run it as a widget. On the chrome: // extensions chrome service page there is a button Download unpacked extension . Using it, select the folder

and the extension is immediately displayed in the list of “widgets” next to the address bar.

From this point on, the extension can already be tested: change popup.html , and see the changes by rediscovering the “widget” by clicking on its icon.

Publish to webstore

To begin with, the possibility of publishing the first 20 extensions costs $ 5 . It occurs in the webstars dashboard , for this you will need to upload a zip-archive of the contents of the extension folder and work on advertising texts and pictures.

Preparing to publish an extension

The first part of the description of the extension will be displayed from the description property of the extension manifest, the rest is added to Detailed description in the extension management on the webstore.

The extension has flexible publishing options: you can select regions of the world to publish, as well as the visibility of the extension.

It must be remembered that if you choose only RF for publication, the extension will not appear in other countries. I came across this while in Thailand: I could not understand why, after 2 days, the extension is not being searched for in the store, even by its direct name.

Advanced options

I have described the necessary steps for publishing the simplest extension so that the process is understandable. Now I want to highlight some of the details for writing a more complex “widget“.

The essence of my expansion is in using foreign APIs for getting information. For this, I need at least localStorage to memorize authorization tokens. 

I used "permissions": ["storage"] in my manifest.


In most cases, API developers propose an OAuth2 protocol for authorization. 

If you are not familiar with this protocol: it offers a secure process of authentication and authorization of the application on behalf of the user without access to the login / password by this application.

The protocol describes several  methods for authorization . Ideally, use Authorization Code Flow, which assumes that the application has a backend ; The API redirects the user with the Auth code to the application, and the application on the backend exchanges it for a token.

There is also a simplified Implicit Flow , which allows you to log in without a backend: API, after logging in, redirects the user to an application with a token in the URL.

How to use this “redirect” authorization in chromium expansion? Start a website? It turns out that not necessarily.

My crutches

Initially, I undertook to integrate with Gitlalb and Trello. With Gitlab, everything turned out to be “simple”: you send the user to the admin area of ​​his Gitlab so that he can make the token and give it to you. I didn’t have to bother with this approach for a long time, I just made a field for entering a token and described how to get it.

Trello provided OAuth2, I immediately noticed that it has an implicit flow , but a bit strange: the token is displayed on their / approve page in this form

Without becoming deeper, I also made a token input field in my extension and described to the user how to do it.

The right way

As usual, a good decision does not come immediately. I stumbled upon it when I started integrating with Jira, which has only Authorization Code Flow.

Somehow I accidentally stumbled upon  chrome.identity : the functionality of the browser, which has already implemented all the crutches for authorization. This functionality requires the inclusion of identity in the permissions of the manifest. I added my manifesto: "permissions": ["storage", "identity"] .

As I already said: each extension has a chrome-extension URL : // <id> / . This address is not good for anything, but chrome.identity provides the real URL https: // <app-id> / *which can be passed to the API with OAuth2 as a redirectUrl. The API, after authorization, will send the user to it with additional parameters, whether it be authCode or token, and chrome will pick them up and pass them to your js-callback extensions.

To do this, use chrome.identity.launchWebAuthFlow (), which opens the API authorization page in a new window:

        'url': JiraApi.url(),
        'interactive': true

Immediately I will say: this window does not look quite like the window of the main browser, which would have raised questions for me if I were a regular user, since it looks like a phishing block, not a window. Maybe this is just my perception, it can only be so in my OS .

Login window chrome.identity.launchWebAuthFlow

Other options

When there is an idea to implement any functionality, I recommend google chrome API, since it already has a lot of similar features that will facilitate your work. For example, the full  manifest.json is impressive:

  // Required
  "app": {
    "background": {
      // Optional
      "scripts": ["background.js"]
  "manifest_version": 2,
  "name": "My App",
  "version": "versionString",
  // Recommended
  "default_locale": "en",
  "description": "A plain text description",
  "icons": {...},
  // Optional
  "action_handlers": ["new_note"],
  "author": ...,
  "automation": ...,
  "bluetooth": {
    "uuids": ["1105", "1006"]
  "commands": {...},
  "current_locale": ...,
  "event_rules": [{...}],
  "externally_connectable": {
    "matches": ["*://**"]
  "file_handlers": {...},
  "file_system_provider_capabilities": {
    "configurable": true,
    "multiple_mounts": true,
    "source": "network"
  "import": [{"id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}],
  "key": "publicKey",
  "kiosk": {
    "always_update": ...,
    "required_platform_version": ...
  "kiosk_enabled": true,
  "kiosk_only": true,
  "kiosk_secondary_apps": ...,
  "minimum_chrome_version": "versionString",
  "nacl_modules": [...],
  "oauth2": ...,
  "offline_enabled": true,
  "optional_permissions": ["tabs"],
  "permissions": ["tabs"],
  "platforms": ...,
  "requirements": {...},
  "sandbox": [...],
  "short_name": "Short Name",
  "signature": ...,
  "sockets": {
    "tcp": {
      "connect": "*"
    "udp": {
      "send": "*"
  "storage": {
    "managed_schema": "schema.json"
  "system_indicator": ...,
  "update_url": "http://path/to/updateInfo.xml",
  "url_handlers": {...},
  "usb_printers": {
    "filters": [...]
  "version_name": "aString",
  "webview": {...}

Pre-dealing with all the possibilities may be too wasteful, because their huge amount.

Moreover, only the js-side of the expansion itself can increase to a large size.

My current scheme


A little worth mentioning is the promotion of its expansion. A feature of the “widgets” is that they are aimed at desktop users who in recent years have become a minority.

I tried contextual advertising and advertising in social networks. Got a little experience and zero conversion. 

contextual advertising

My experience has so far limited itself to one site, I cannot speak for the rest, but I think the same is there.

It turns out that in contextual advertising of Yandex, you cannot target by devices and browsers. So if your extension is only for chrome, you’ll also have to show ads to people sitting on other browsers, whose transitions will bring only unnecessary losses.

I did not want to make a separate site for my extension, so I advertised its page in the webstore. The disadvantage of this approach is that you can only trust the statistics of the advertising account and cannot see how users behave on the advertised page.

Social networks

They just belong to the category of sites on which the desktop is a dying minority.

Vkontakte provides mobile and full version targeting of its site. But this checkbox is hidden at the very end of the settings, I personally did not notice it before I merged the budget and saw sad coverage in statistics.

In fact, that day mobile views were much larger

Last thoughts

I believe that expansion is a powerful tool for people working on the Internet, because in the browser we spend a lot of time, which sometimes we want to optimize. For example, a Google translator widget that translates text when selected is a good optimization example. Solving the problem of a huge number of open tabs “later” I also decided using the widget.

Writing extensions gives you experience in exploring the underwater part of the iceberg “Chrome” and writing “frontend” (especially if you are a backend developer). Extensions can be written on the same React JS from which you can jump on writing applications for mobile devices. The process of writing is very similar.

Also popular now: