Last week, I made a small extension for the Google Chrome browser to replace the default “New Tab” page. I had previously tried extensions like Panda, but found them too distracting, and wanted something that would be nice to look at, but not too attention-grabbing.

InstaChrome is an extension for Google Chrome that allows you display the latest 6 instagram posts from a tag of your choice. 

InstaChrome Screenshot


With the exception of a few things, making this was like making a regular javascript application. As always, you can view the full app on my github. But here is an overview of how I made the extension.

Making a Chrome Extension

There were two key things that this extension different from a regular web app - the manifest.json file, and storing data in the browser’s local storage. 

manifest.json

The manifest.json file is a required file that stores all the metadata for a Chrome extension. It is where we declare basic information such as the name and description of the extension, as well as functional information such as the permissions required and any overrides.

This was my manifest.json file - 

{
  // The version of manifest.json we are using
  "manifest_version": 2,

  // Required information about the extension
  "name": "InstaChrome",
  "description": "An extension for chrome that displays Instagram posts from a tag of your choice.",
  "version": "1",

  // Overriding the default behaviour for a new tab to redirect to our index.html file
  "chrome_url_overrides":{
    "newtab" : "index.html"
  },

  // Allow use of chrome local storage
  "permissions": [
    "storage"
  ],

  // Allow requests from api.instagram.com
  "content_security_policy": "script-src 'self' 'unsafe-eval' https://api.instagram.com; object-src 'self'"
}

Working With Local Storage

With this extension, I wanted to be able to save the last tag searched for in local storage so a user wouldn't need to search again everytime they open a new tab. To do this, we can use the chrome.storage API. 

To store a variable, we use the set function on the storage area we want, in this case, local

chrome.storage.local.set({label : value}, function(){  
  // do something
});

To retrieve data based on a given label, we use the get function - 

chrome.storage.local.get(label, function(result) {  
  // do something
})

To remove data from storage, we use the remove function - 

chrome.storage.local.remove(label, function() {  
  // do something
})

InstaChrome

Having set all that up, this was my main app file - 

"use strict";
$(document).ready(function() {

  var request = function() {
    chrome.storage.local.get("tag", function(result) {

      var tag = result.tag;
      var cleanTag;

      // Display # on the front end, but remove # for the cleanTag variable
      if ( tag.indexOf("#") === -1 ) {
        cleanTag = tag;
        $('input[type="text"]').val('#'+tag);
      } else {
        cleanTag = tag.split('#')[1];
      }

      cleanTag = cleanTag.replace(/\s/g, "");

      var requestUrl = 'https://api.instagram.com/v1/tags/'+cleanTag+'/media/recent?access_token='+accessToken+'&callback=?';

      $.getJSON(requestUrl, {}, function(data) {

        var items = [];

        // Get only 6 items
        for (var i=0; i < 6; i++) {
          items.push(data.data[i]);
        }

        // Setup Handlebars templating
        var source = $('#grams-template').html();
        var template = Handlebars.compile(source);
        var output = template( {Grams: items} );

        $('.loading').hide();

        if (data.data.length === 0) {
          // Show error messages if no images for this tag
          $('.message-error').show();
        } else {
          // Else, display the images in the template
          $("#grams").html(output).fadeIn();
        }
      });

    }); // end get local storage
  }; // end request

  // When users search
  $('#search').on('submit', function() {

    // Clear messages and any previous images, and show loading animation
    $('.message').hide();
    $("#grams").html("");
    $('.loading').show();

    var searchInput = $('#searchText').val();

    // Set the search text to local storage
    chrome.storage.local.set({"tag" : searchInput}, function(){
      request();
    });

    return false;
  })

  // On load of the new tab, check if there is any tag previously stored
  chrome.storage.local.get("tag", function(result) {

    if ( result.tag ) {
      request();
      $('input[type="text"]').val(result.tag);
    } else {
      $('.loading').hide();
      $('.message-welcome').show();
    }

  })

});

 

You can check out the extension on github or download it from the Chrome store. If you use this extension, or have any feedback on how I can improve on it, do leave a comment below.