Day 29: Yeoman Chrome Generator--Write Your First Google Chrome Extension

Today for my 30 day challenge, I decided to learn how to write a Chrome extension. After some research, I found out that there is a Yeoman generator for writing Chrome extensions. The extension that we will write in this blog post blocks us from accessing Facebook, Twitter, LinkedIn, and other social web sites during the office time. This blog post will not cover Yeoman basics so please refer to my day 24 blog for a getting started with Yeoman post.

Chrome Extension

Chrome Extension Usecase

We will write a very simple extension which will block us from access social websites like Facebook, Twitter, etc. during office time(9 am to 6pm). If a user access facebook or twitter, then he/she will see the following page.

Chrome Extension

I am not blocking Google + :)

Install Yeoman

To install yeoman type the following command. This command assumes you have Node and Npm installed on your machine.

$ npm install -g yeoman

The command shown above will install yeoman globally. The -g option is used to signify a global install. This will also install Grunt and bower if not already installed.

Install Yeoman Chrome Generator

Yeoman depends on generators to scaffold the application code. There are generators for all modern JavaScript MV* frameworks. In this blog, we will use the Chrome generator. NPM is used to install the generators.

$ npm install -g generator-chrome-extension

Github Repository

The code for today's demo application is available on github: day29-chrome-extension.

Create Chrome Extension

Now that we have covered all the basics let us start with the chrome extension development.

Create a new directory at any convenient location on the file system for the extension and change directory to it.

$ mkdir no-socializing
$ cd no-socializing

Next run the yo chrome-extension command and it will ask you few questions as shown below.

Chrome Extension

Lets go through all these questions one by one.

  1. It first asks the name that we would like to give the extension. The default name is the folder name.
  2. Then it asks the purpose of the extension.
  3. Next, it asks us whether we want to use any UI action. I used Browser UI action. The browser action allows us to place a clickable icon right next to Chrome's Omnibox for easy access. Clicking that icon will open an html file.
  4. Next, it asks us if we would like to add more UI features. We added options page and Omnibox features.
  5. Lastly, it asks which permissions we would like to give to the extension. Please refer to documentation for more information.

You can install the unpacked extension to the chrome as shown below. Check the Developer Mode and then click on Load unpackaged extension and give it the app folder under no-socializing directory.

Chrome Extension

After installation, you will see the following.

Chrome Extension

Update Background.js

The chrome extension behavior is specified in background.js file under app/scripts folder. Copy the following code and paste it in the background.js source file.

'use strict';
 
chrome.webRequest.onBeforeRequest.addListener(
    function(details) {
        var currentTime = new Date();
        if(isOfficeTime(currentTime) && isWeekday(currentTime)){
            return {redirectUrl: chrome.extension.getURL('index.html')};    
        }
        return details.url;
    },
    {
        urls: [
            "*://*.facebook.com/*",
            "*://*.twitter.com/*",
            "*://*.gmail.com/*",
        ],
        types: ["main_frame", "sub_frame", "stylesheet", "script", "image", "object", "xmlhttprequest", "other"]
    },
    ["blocking"]
);
 
function isOfficeTime(currentTime){
    var hour = currentTime.getHours();
    return hour > 9 && hour < 18;
}
 
function isWeekday(currentTime){
    var dayOfWeek = currentTime.getDay();
    return dayOfWeek >= 1 && dayOfWeek <= 5;
}

The code shown above does the following :

It listens to onBeforeRequest event which fires when a request is about to occur. The addListener function takes three parameters :

  1. A callback function which will execute when the event fires.
  2. RequestFilter object describing filters to apply to webRequest events. We specified a list of URL patterns which will be filtered.
  3. An array contains the string 'blocking' (only allowed for specific events), the callback function is handled synchronously.

We also defined a couple of functions to check the current time and day of the week. It only blocks social websites during weekdays from 9am to 6pm.

The code shown above uses WebRequest API. We need to give the extension access to chrome.webRequest API. This is done using webRequest permission. As the extension uses the chrome.webRequest API in a blocking fashion, we will also have to give webRequestBlocking permission. Open the manifest.json under app directory and update the permissions section.

"permissions": [
    "webRequest",
    "tabs",
    "http://*/*",
    "https://*/*",
    "webRequestBlocking"
  ]

The last thing we need to add is index.html. This will be rendered when user makes request to Facebook, Twitter, etc.

<!DOCTYPE html>
<html lang="en">
<head>
  <title>No Socializing</title>
  <link rel="stylesheet" href="/styles/main.css">
</head>
<body>
  <h1>NO, Socializing</h1>
  <img src="/images/no-social-media.jpg" height="450" width="450">
  <h2>It's Office Time  Dude</h2>
</body>
</html>

You can download the image from github repository.

Now reload the extension and go to http://facebook.com or http://twitter.com. If the current time is between 9am and 6pm then you will see the following.

Chrome Extension

That's it for today. Keep giving feedback.

What's Next