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 extensionI 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 in the 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!".
Structure

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.jsonExtensions 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 website, only as a “protocol” there will be a chrome-extension, for example
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 web site, except for a couple of possibilities, for example: following links only work with
target = "_ blank" . There are also technical limitations 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
Download unpacked extension button. Use it to select a 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 for the publication of the extensionThe 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 expansion will not appear in other countries. I came across it 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 remember authorization tokens.
I used
"permissions": ["storage"] in my manifest.
Oauth2
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 deep, 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 : browser functionality, which has already implemented all the crutches for authorization. This functionality requires the inclusion of
identity in the manifest permissions. I added my manifest:
"permissions": ["storage", "identity"] .
As I already said: each extension has a URL of the
chrome-extension type: // <id> / . This address is not suitable for anything, but
chrome.identity provides the real URL
https: // <app-id> .chromiumapp.org / * , which can be passed to the API with OAuth2 as the redirectUrl. The API, after authorization, will send the user to it with additional parameters, be it 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:
chrome.identity.launchWebAuthFlow( { 'url': JiraApi.url(), 'interactive': true }, jira.callback() );
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.launchWebAuthFlowOther 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": ["*://*.example.com/*"] }, "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 large sizes.
My current schemePromotion
Little is worth mentioning 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 others, but I think the same is there.
It turns out that in the 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 tick is hidden at the very end of the settings, I personally did not notice it before I leaked the budget and saw sad statistics in the statistics.

In fact, that day mobile views were much more
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. I also decided to solve the problem of a huge number of open tabs “later” using a widget.
Writing extensions gives you experience in exploring the underwater part of the iceberg “Chrome” and writing the “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.