Wern Ancheta

Adventures in Web Development.

Creating a Chrome Extension

| Comments

In this tutorial I’ll be showing you how to create a very basic chrome extension. One that would allow us to schedule posts with the Ahead project that I created. Here’s how it will work:

  1. User clicks on the extension on a page that he wants to share on a future time.
  2. The extension makes a request to the server where Ahead is currently hosted.
  3. The server returns a response and it is then outputted by the extension.

Creating the Extension

Before anything else we need to create the manifest.json file. This is the most important file since chrome won’t be able to recognize our extension if we do not have this file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
  "manifest_version": 2,
  "name": "Ahead",
  "version": "1.0",
  "description": "Easily schedule posts",

  "browser_action": {
    "default_icon": "icon.png"
  },

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

  "content_scripts": 
    [
        {
            "matches":["<all_urls>"],
            "js":["content.js"],
            "run_at": "document_end"
        }
    ],
  
  "permissions": ["<all_urls>", "storage"],
  "options_page": "options.html"
}

Breaking it down:

  • manifest_version – this is the version of the manifest file. The Chrome browser has been around for quite a while now. So are the extensions that have been written when it first came out. Currently the latest version that we can assign to a manifest file is 2.

  • name – the name you want to give to the extension.

  • version – the version of the extension.
  • description – a descriptive text you want to show your users. This is the text that will show right under the name of the extension when the user accesses the chrome://extensions page.
  • browser_action – used to specify the element which will trigger the extension. In this case we want an icon to be the trigger so we set the default_icon. The value would be the filename of the icon.
  • content_scripts – these are the scripts that run in the context of the current web page. The matches property is where you specify an array of URL’s where the content scripts can run. In this case we just set a special value called "<all urls>". This way the script can run from any webpage. Next is the js property where we specify an array of items containing the path to the content scripts. Last is the run_at property where we specify when to run the content scripts. We just set it to document_end so we can make sure that the whole page is loaded before we execute our script.
  • background – used to specify the background scripts. Content scripts only has access to the elements in the current page but not the Chrome API methods. So we need a background script in order to access those methods. This property simply takes up a single property called scripts where you specify an array of the background scripts you wish to use. In thise case were just going to use a single background.js file.
  • permissions – this is where we can specify an array containing the list of items that the extension needs to use or has access in. In this case were just going to use "<all_urls>" and storage. We use storage to have access to the methods used for saving custom settings for the extension. In our case the setting would be the api key required by Ahead.
  • options_page – used for specifying which HTML file will be used for the options page.

Next let’s proceed with the options page:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
<head><title>Ahead</title></head>
<body>

    API Key:
    <input type="text" id="api_key">

    <button id="save">Save</button>

    <script src="options.js"></script>
</body>
</html>

You can use css just like you would in a normal HTML page if you want. But for this tutorial we won’t. The options page is pretty minimal. All we need is the actual field, a button to save the settings and then a link to the options page JavaScript file.

Here’s the options.js file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function save_options(){
  var api_key = document.getElementById('api_key').value;

  chrome.storage.sync.set({
    'api_key': api_key
  },
  function(){
    alert('API Key Saved!');
  });
}


function restore_options(){

  chrome.storage.sync.get({
    'api_key': ''
  },
  function(items){
    document.getElementById('api_key').value = items.api_key;
  });
}
document.addEventListener('DOMContentLoaded', restore_options);
document.getElementById('save').addEventListener('click',
    save_options);

In the above file we declared 2 methods. save_options and restore_options. save_options is used for saving the settings to chrome storage. And restore_options is for retrieving the settings from the storage and populating the value for each of the fields. In the options.js file we got access to the chrome storage API. The main methods that were using are the sync.set and sync.get. We use sync.set to save the settings in the chrome storage and then output an alert box saying the settings are saved when its successful. sync.get on the other hand is used for retrieving the existing setting from chrome storage and then we use the retrieved value to populate the text field. The save_options method is called when the save button is clicked. And the restore_options method is called when the DOM of the options page has been fully loaded.

Next is the background.js file. We primarily use this file to listen for the click event on the browser_action which is basically the icon of extension that is located on the upper right corner of Chrome:

1
2
3
4
5
6
7
chrome.browserAction.onClicked.addListener(function(tab){

  chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    var activeTab = tabs[0];
    chrome.tabs.sendMessage(activeTab.id, {"message": "clicked_browser_action"});
  });
});

You don’t need to worry about the code above too much. All it does is listen for the click event on the icon of the extension. It then uses the tabs.sendMessage method to send a message to the current tab that hey the icon extension has been clicked. This then brings us to the content.js file which basically just waits for this message to be sent. Once it receives the message we then retrieve the api key using the sync.get method. Once we retrieved the api key we make a POST request to the Ahead URL which is responsible for accepting POST requests for posts to be published. The content would be the title of the current page and then its URL. We then construct a new form data and supply the queue, api_key and content as the fields. We set the queue to true because we want to schedule the post to be published later. If you set it to false then it will be published immediately. Next is the api_key. We simply supply what we got from chrome storage as the value. And last is the content. We then send this form data to the Ahead URL. Finally we listen for the onload event on the request. This event is fired up whenever the request is successful. All we have to do is parse the response since its a JSON string. We then alert the value for the text property. Which is basically just a message saying that the post was scheduled and when it will be published. If we do get an error, the onerror event is fired and we simply tell the user to try again by using an alert.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse){

    chrome.storage.sync.get({
        'api_key': ''
    },
    function(items){
        var api_key = items.api_key;

        var http_request = new XMLHttpRequest();
        http_request.open('POST', 'http://ec2-54-68-251-216.us-west-2.compute.amazonaws.com/api/post', true);
        var content = document.title + ' ' + window.location.href;
        var form_data = new FormData();
        form_data.append('queue', true);
        form_data.append('api_key', api_key);
        form_data.append('content', content);
        http_request.send(form_data);

        http_request.onload = function(){
            if(http_request.status >= 200 && http_request.status < 400){
              var response_data = JSON.parse(http_request.responseText);
              alert(response_data.text);
            }
        };


        http_request.onerror = function() {
            alert('Something went wrong while trying to post. Please try again');
        };
    });


  }
);

Installing the Extension

Now were ready to actually install the extension. You can do that by enabling developer mode on the chrome extensions page:

1
chrome://extensions/

This will show you 3 new buttons: load unpacked extension, pack extension and update extensions now. All we need is the first one. Click on it then select the folder that contains the manifest.json file on its root directory. Chrome will then list it as one of the available extensions:

extensions

Once its loaded, click on the ‘options’ link to access the options page. From there add the api key which you can get from the Ahead website.

At this point all of the new tabs that you open or the existing tabs which you reload would be useable with the extension. Just click on the extension icon and it will schedule a post using the title of the page and its URL as the content.

Conclusion

That’s it! In this tutorial you’ve learned the basics of how to create a chrome extension. You’ve learned how to listen for the click event on the extension icon, how to add an options page and how to get the details from the current page.

Comments