Building Chrome Extension with Vue.js

Building Chrome Extension with Vue.js

In this tutorial, I’m going to show you how to build a simple extension for Chrome, which alters the behavior of the new tab page. For the JavaScript part of the extension, I’ll be using the Vue.js framework,

The good news is that browser extensions aren’t difficult to write. They can be created using the web technologies you’re already familiar with — HTML, CSS and JavaScript — just like a regular web page. However, unlike regular web pages, extensions have access to a number of browser-specific APIs, and this is where the fun begins.

The Basics of a Chrome Extension

The core part of any Chrome extension is a manifest file and a background script. The manifest file is in a JSON format and provides important information about an extension, such as its version, resources, or the permissions it requires. A background script allows the extension to react to specific browser events, such as the creation of a new tab.

To demonstrate these concepts, let’s start by writing a “Hello, World!” Chrome extension.

Make a new folder called hello-world-chrome and two files: manifest.json and background.js:

mkdir hello-world-chrome
cd hello-world-chrome
touch manifest.json background.js

Open up manifest.json and add the following code:

{
  "name": "Hello World Extension",
  "version": "0.0.1",
  "manifest_version": 2,
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  }
}

The name, version and manifest_version are all required fields. The name and version fields can be whatever you want; the manifest version should be set to 2 (as of Chrome 18).

The background key allows us to register a background script, listed in an array after the scripts key. The persistent key should be set to false unless the extension uses chrome.webRequest API to block or modify network requests.

Now let’s add the following code to background.js to make the browser say hello when the extension is installed:

chrome.runtime.onInstalled.addListener(() => {
  alert('Hello, World!');
});

Finally, let’s install the extension. Open Chrome and enter chrome://extensions/ in the address bar. You should see a page displaying the extensions you’ve installed.

As we want to install our extension from a file (and not the Chrome Web Store) we need to activate Developer mode using the toggle in the top right-hand corner of the page. This should add an extra menu bar with the option Load unpacked. Click this button and select the hello-world-chrome folder you created previously. Click Open and you should see the extension installed and a “Hello, World!” popup appear.

Congratulations! You just made a Chrome extension.

Overriding Chrome’s New Tab Page

The next step will to have our extension greet us when we open up a new tab. We can do this by making use of the Override Pages API.

Note: before you progress, please make sure to disable any other extensions which override Chrome’s new tab page. Only one extension at a time may alter this behavior.

We’ll start off by creating a page to display instead of the new tab page. Let’s call it tab.html. This should reside in the same folder as your manifest file and background script:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My New Tab Page!</title>
</head>
<body>
  <h1>My New Tab Page!</h1>
  <p>You can put any content here you like</p>
</body>
</html>

Next we need to tell the extension about this page. We can do so by specifying a chrome_url_overrides key in our manifest file, like so:

"chrome_url_overrides": {
  "newtab": "tab.html"
}

Finally, you need to reload the extension for the changes to take effect. You can do this by clicking the reload icon for the Hello World extension on Chrome’s extensions page.

Now, when you open a new tab, you should be greeted by your custom message.

Adding Vue to the Extension

Now we have a very basic implementation of our extension up and running, the time has come to think about what the rest of the desired functionality will look like. When a user opens a new tab, I would like the extension to:

  • Fetch a joke from the wonderful icanhazdadjoke.com.
  • Display that joke in a nicely formatted manner to the user.
  • Display a button for the user to favorite the joke. This will save the joke to chrome.storage.
  • Display a button for the user to list favorited jokes.

You could, of course, do all of this with plain JavaScript, or a library like jQuery — and if that’s your thing, feel free!

For the purposes of this tutorial, however, I’m going to implement this functionality using Vue and the awesome vue-web-extension boilerplate.

Using Vue allows me to write better, more organized code faster. And as we’ll see, the boilerplate provides several scripts that take the pain out of some of the common tasks when building a Chrome extension (such as having to reload the extension whenever you make changes).

vue-web-extension-boilerplate

This section assumes that you have Node and npm installed on your computer. If this isn’t the case, you can either head to the project’s home page and grab the relevant binaries for your system. I would recommend using a version manager.

We’ll also need Vue CLI installed and the @vue/cli-init package:

npm install -g @vue/cli
npm install -g @vue/cli-init

With that done, let’s grab a copy of the boilerplate:

vue init kocal/vue-web-extension new-tab-page 

This will open a wizard which asks you a bunch of questions. To keep this tutorial focused, I answered as follows:

? Project name new-tab-page
? Project description A Vue.js web extension
? Author James Hibbard <[email protected]>
? License MIT
? Use Mozilla's web-extension polyfill? No
? Provide an options page? No
? Install vue-router? No
? Install vuex? No
? Install axios? Yes
? Install ESLint? No
? Install Prettier? No
? Automatically install dependencies? npm

You can adapt your answers to suit your preferences, but the main thing to be certain of is that you choose to install axios. We’ll be using this to fetch the jokes.

Next, change into the project directory and install the dependencies:

cd new-tab-page
npm install

And then we can build our new extension using one of the scripts the boilerplate provides:

npm run watch:dev 

This will build the extension into a dist folder in the project root for development and watch for changes.

To add the extension to Chrome, go through the same process as outlined above, making sure to select the dist folder as the extension directory. If all goes according to plan, you should see a “Hello world!” message when the extension initializes.

Project Setup

Let’s take a minute to look around our new project and see what the boilerplate has given us. The current folder structure should look like this:

.
├── dist
│   └── <the built extension>
├── node_modules
│   └── <one or two files and folders>
├── package.json
├── package-lock.json
├── scripts
│   ├── build-zip.js
│   └── remove-evals.js
├── src
│   ├── background.js
│   ├── icons
│   │   ├── icon_128.png
│   │   ├── icon_48.png
│   │   └── icon.xcf
│   ├── manifest.json
│   └── popup
│       ├── App.vue
│       ├── popup.html
│       └── popup.js
└── webpack.config.js

As you can see, from the config file in the project root, the boilerplate is using webpack under the hood. This is awesome, as this gives us Hot Module Reloading for our background script.

The src folder contains all of the files we’ll be using for the extension. The manifest file and background.js should be familiar, but also notice a popup folder containing a Vue component. When the boilerplate builds the extension into the dist folder, it will pipe any .vue files through the vue-loader and output a JavaScript bundle which the browser can understand.

Also in the src folder is an icons folder. If you look in Chrome’s toolbar, you should see a new icon for our extension (also known as the browser action). This is being pulled from this folder. If you click it, you should see a popup open which displays “Hello world!” This is created by popup/App.vue.

Finally, note a scripts folder containing two scripts — one to remove eval usages to comply with the Content Security Policy of Chrome Web Store and one to package your extension into a .zip file, which is necessary when uploading it to the Chrome Web Store.

There are also various scripts declared in the package.json file. We’ll be using npm run watch:dev for developing the extension and later on npm run build-zip to generate a ZIP file to upload to the Chrome Web Store.

Using a Vue Component for the New Tab Page

Start off by removing the annoying alert statement from background.js.

Now let’s make a new tab folder in the src folder to house the code for our new tab page. We’ll add three files to this new folder — App.vue, tab.html,, tab.js:

mkdir src/tab
touch src/tab/{App.vue,tab.html,tab.js}

Open up tab.html and add the following:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>New Tab Page</title>
  <link rel="stylesheet" href="tab.css">
</head>
<body>
  <div id="app"></div>
  <script src="tab.js"></script>
</body>
</html>

Nothing special going on here. This is a simple HTML page which will hold our Vue instance.

Next, in tab.js add:

import Vue from 'vue';
import App from './App';

new Vue({
  el: '#app',
  render: h => h(App)
});

Here we import Vue, pass a selector for the element that we want it to replace with our application, then tell it to render our App component.

Finally, in App.vue:

<template>
  <p>{{ message }}</p>
</template>

<script>
export default {
  data () {
    return {
      message: "My new tab page"
    }
  }
}
</script>

<style scoped>
p {
  font-size: 20px;
}
</style>

Before we can use this new tab page, we need to update the manifest file:

{
  "name":"new-tab-page",
  ...
  "chrome_url_overrides": {
    "newtab": "tab/tab.html"
  }
}

And we also need to have the boilerplate compile our files and copy them over to the dist folder, so that they’re available to the extension.

Alter webpack.config.js like so, updating both the entry and plugins keys:

entry: {
  'background': './background.js',
  'popup/popup': './popup/popup.js',
  'tab/tab': './tab/tab.js'
}
plugins: [
  ...
  new CopyWebpackPlugin([
    { from: 'icons', to: 'icons', ignore: ['icon.xcf'] },
    { from: 'popup/popup.html', to: 'popup/popup.html', transform: transformHtml },
    { from: 'tab/tab.html', to: 'tab/tab.html', transform: transformHtml },
    ...
  })

You’ll need to restart the npm run watch:dev task for these changes to take effect. Once you’ve done this, reload the extension and open a new tab. You should see “My new tab page” displayed.

Fetching and Displaying Jokes

Okay, so we’ve overriden Chrome’s new tab page and we’ve replaced it with a mini Vue app. Now let’s make it do more than display a message.

Alter the template section in src/tab/App.vue as follows:

<template>
  <div>
    <div v-if="loading">
      <p>Loading...</p>
    </div>
    <div v-else>
      <p class="joke">{{ joke }}</p>
    </div>
  </div>
</template>

Change the <script> section to read as follows:

<script>
import axios from 'axios';

export default {
  data () {
    return {
      loading: true,
      joke: "",
    }
  },
  mounted() {
    axios.get(
      "https://icanhazdadjoke.com/",
      { 'headers': { 'Accept': 'application/json' } }
    )
      .then(res => {
        this.joke = res.data.joke
        this.loading = false;
      });
  }
}
</script>


And finally, change the <style> section to read as follows:

<style>
body {
  height: 98vh;
  text-align: center;
  color: #353638;
  font-size: 22px;
  line-height: 30px;
  font-family: Merriweather,Georgia,serif;
  background-size: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.joke {
  max-width: 800px;
}
</style>

If you’re running the npm run watch:dev task, the extension should automatically reload and you should see a joke displayed whenever you open a new tab page.

Once you’ve verified it’s working, let’s take a minute to understand what we’ve done.

In the template, we’re using a v-if block to either display a loading message or a joke, depending on the state of the loading property. Initially, this will be set to true (displaying the loading message), then our script will fire off an Ajax request to retrieve the joke. Once the Ajax request completes, the loading property will be set to false, causing the component to be re-rendered and our joke to be displayed.

In the <script> section, we’re importing axios, then declaring a couple of data properties — the aforementioned loading property and a joke property to hold the joke. We’re then making use of the mounted lifecycle hook, which fires once our Vue instance has been mounted, to make an Ajax request to the joke API. Once the request completes, we update both of our data properties to cause the component to re-render.

So far, so good.

Persisting Jokes to Chrome’s Storage

Next, let’s add some buttons to allow the user to favorite a joke and to list out favorited jokes. As we’ll be using Chrome’s storage API to persist the jokes, it might be worth adding a third button to delete all of the favorited jokes from storage.

Add the buttons to the v-else block:

<div v-else>
  <p class="joke">{{ joke }}</p>

  <button @click="likeJoke" :disabled="likeButtonDisabled">Like Joke</button>
  <button @click="logJokes" class="btn">Log Jokes</button>
  <button @click="clearStorage" class="btn">Clear Storage</button>
</div>

Nothing too exciting here. Note the way that we are binding the like button’s disabled property to a data property on our Vue instance to determine its state. This is because a user shouldn’t be able to like a joke more than once.

Next, add the click handlers and the likeButtonDisabled to our script section:

export default {
  data () {
    return {
      loading: true,
      joke: "",
      likeButtonDisabled: false
    }
  },
  methods: {
    likeJoke(){
      chrome.storage.local.get("jokes", (res) => {
        if(!res.jokes) res.jokes = [];
        res.jokes.push(this.joke)
        chrome.storage.local.set(res);
        this.likeButtonDisabled = true;
      });
    },
    logJokes(){
      chrome.storage.local.get("jokes", (res) => {
        if(res.jokes) res.jokes.map(joke => console.log(joke))
      });
    },
    clearStorage(){
      chrome.storage.local.clear();
    }
  },
  mounted() { ... }
}

Here we’ve declared three new methods to deal with the three new buttons.

The likeJoke method looks for a jokes property in Chrome’s storage. If it’s missing (that is, the user has yet to like a joke), it initializes it to an empty array. Then it pushes the current joke onto this array and saves it back to storage. Finally it sets the likeButtonDisabled data property to true, disabling the like button.

The logJokes method also looks for a jokes property in Chrome’s storage. If it finds one, it loops over all of its entries and logs them to the console.

Hopefully what the clearStorage method does is clear.

Go ahead and try this new functionality in the extension and satisfy yourself that it works.

Adding Some Polish to the Extension

Okay, so that seems to work, but the buttons are ugly and the page is a little plain. Let’s finish off this section by adding some polish to the extension.

As a next step, install the vue-awesome library. This will allow us to use some Font Awesome icons in on our page and make those buttons look a bit nicer:

npm install vue-awesome 

Register the library with our Vue app in src/tab/tab.js:

import Vue from 'vue';
import App from './App';
import "vue-awesome/icons";
import Icon from "vue-awesome/components/Icon";

Vue.component("icon", Icon);

new Vue({
  el: '#app',
  render: h => h(App)
});

Now alter the template like so:

<template>
  <div>
    <div v-if="loading" class="centered">
      <p>Loading...</p>
    </div>
    <div v-else>
      <p class="joke">{{ joke }}</p>

      <div class="button-container">
        <button @click="likeJoke" :disabled="likeButtonDisabled" class="btn"><icon name="thumbs-up"></icon></button>
        <button @click="logJokes" class="btn"><icon name="list"></icon></button>
        <button @click="clearStorage" class="btn"><icon name="trash"></icon></button>
      </div>
    </div>
  </div>
</template>

Finally, let’s add some more styling to the buttons and include a picture of everyone’s favorite dad:

<style>
body {
  height: 98vh;
  text-align: center;
  color: #353638;
  font-size: 22px;
  line-height: 30px;
  font-family: Merriweather,Georgia,serif;
  background: url("https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2018/12/1544189726troll-dad.png") no-repeat 1% 99%;
  background-size: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.joke {
  max-width: 800px;
}

.button-container {
  position: absolute;
  right: 0px;
  top: calc(50% - 74px);
}

.btn {
  background-color: #D8D8D8;
  border: none;
  color: white;
  padding: 12px 16px;
  font-size: 16px;
  cursor: pointer;
  display: block;
  margin-bottom: 5px;
  width: 50px;
}

.btn:hover {
  background-color: #C8C8C8;
}

.btn:disabled {
  background-color: #909090;
}
</style>

The extension should reload. Try opening a new tab and you should see something like this.

Uploading the Extension to the Chrome Web Store

Should you want to make your extension available for others to download, you’d do this via the Chrome Web Store.

The first thing you’ll need in order to do this is a Google account, which you can use to sign in to the Developer Dashboard. You’ll be prompted for your developer details, and before you publish your first app, you must pay a one-time $5 developer signup fee (via credit card).

Next, you need to create a ZIP file for your app. You can do this locally by running the npm run build-zip. This will create a dist-zip folder in your project root, containing a ZIP file ready to upload to the Web Store.

For a minimal extension, this is all you’d really need to do. However, before you upload anything, it’s worth reading the official Publish in the Chrome Web Store guide.

Conclusion

And with that, we’re done. In this tutorial, I’ve highlighted the main parts of a Chrome extension and shown how to use the vue-web-extension boilerplate to build an extension using Vue.js. We finished off by looking at how to upload an extension to the Web Store and everything that involves.

I hope you enjoyed this tutorial and can use it to get started building Chrome extensions of your own

The code for this tutorial can be found on GitHub.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading

Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)

Nuxt.js - Vue.js on Steroids

Build Web Apps with Vue JS 2 & Firebase

Build a Progressive Web App In VueJs

Build a Basic CRUD App with Vue.js and Node

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

Top Vue.js Developers in USA

Top Vue.js Developers in USA

Vue.js is an extensively popular JavaScript framework with which you can create powerful as well as interactive interfaces. Vue.js is the best framework when it comes to building a single web and mobile apps.

We, at HireFullStackDeveloperIndia, implement the right strategic approach to offer a wide variety through customized Vue.js development services to suit your requirements at most competitive prices.

Vue.js is an open-source JavaScript framework that is incredibly progressive and adoptive and majorly used to build a breathtaking user interface. Vue.js is efficient to create advanced web page applications.

Vue.js gets its strength from the flexible JavaScript library to build an enthralling user interface. As the core of Vue.js is concentrated which provides a variety of interactive components for the web and gives real-time implementation. It gives freedom to developers by giving fluidity and eases the integration process with existing projects and other libraries that enables to structure of a highly customizable application.

Vue.js is a scalable framework with a robust in-build stack that can extend itself to operate apps of any proportion. Moreover, vue.js is the best framework to seamlessly create astonishing single-page applications.

Our Vue.js developers have gained tremendous expertise by delivering services to clients worldwide over multiple industries in the area of front-end development. Our adept developers are experts in Vue development and can provide the best value-added user interfaces and web apps.

We assure our clients to have a prime user interface that reaches end-users and target the audience with the exceptional user experience across a variety of devices and platforms. Our expert team of developers serves your business to move ahead on the path of success, where your enterprise can have an advantage over others.

Here are some key benefits that you can avail when you decide to hire vue.js developers in USA from HireFullStackDeveloperIndia:

  • A team of Vue.js developers of your choice
  • 100% guaranteed client satisfaction
  • Integrity and Transparency
  • Free no-obligation quote
  • Portal development solutions
  • Interactive Dashboards over a wide array of devices
  • Vue.js music and video streaming apps
  • Flexible engagement model
  • A free project manager with your team
  • 24*7 communication with your preferred means

If you are looking to hire React Native developers in USA, then choosing HireFullStackDeveloperIndia would be the best as we offer some of the best talents when it comes to Vue.js.

Learn how to build Chrome Extensions with Vue.js

Learn how to build Chrome Extensions with Vue.js

As a frontend developer you are able to build your own extensions since it’s basically just HTML, CSS and JavaScript. In this post, you'll learn how to build Chrome extensions with Vue.js

How is a Chrome Extension structured?

A Chrome Extension consist of 5 crucial components

  • Manifest file — consist of all the metadata for the extension like icon paths, descriptions, permissions, version and so on.
  • Background Script — that is the extension’s event handler. It can contain listeners for browser events that you would like to act on in the extension.
  • UI Elements — pretty self describing but it’s the UI elements in the pop-up when you open the extension.
  • Content Script — if you want to read or write to the current webpage that the user is visiting you will need to use a content script.
  • Options Page — the options page contains the users settings for the extension.

Getting started

As a frontend developer you are able to build your own extensions since it’s basically just HTML, CSS and JavaScript. You could go the vanilla way which is great for simple extensions, but for the more complex ones it could be an idea to use a JavaScript framework. Since I had a lot of communication with REST services and dynamic data in general I chose to include my favourite JavaScript framework Vue.js.

I also didn’t want to start from scratch so I started to look for a boilerplate, and found the amazing Vue.js boilerplate from Kocal which uses the Vue CLI.

It contains all the required setup and structure to build an extension, and besides that you also have the possibility to add axios, vue-router, vuex and a Mozilla polyfill during the installation process.

How to

To get up and running you will have to have the Vue CLI installed and then you just have to run the following command…

vue init kocal/vue-web-extension [NAME OF YOUR EXTENSION]

The following process looks something like this:

The result

After the installation you will be presented with a folder structure like this:

Then you will have to go to the extensions page in Chrome, enable developer mode, click Load unpacked and select the dist folder in your extension like I did in the screenshot below. Now you can start building!

Solving a real life issue with a Chrome Extension

As I’m working as a Frontend Developer consultant I have to track all the time I use on projects which has to be registered in Jira. But since Jira doesn’t offer the best time tracking features I use Toggl for the actual time tracking.

After getting tired of moving entries manually to Jira I started to look for tools that could help me sync these, but unfortunately they all come at a pretty high price, and the free ones didn’t work as I wanted them to.

Since I couldn’t find a suitable tool I jumped into building my own extension with the process and tools mentioned above. It was important for me that the extension also looked nice and since Google uses Material design in Chrome it made sense for me to add Vue Material as well. It’s built with Vue.js and contains Material designed Vue components for e.g. inputs, datepicker, buttons and so on.

The obstacle and the solution

The extension uses the Toggl and Jira REST API’s which means that all API calls has to be authenticated. This would normally mean that when a user installs the extension, they would have to set up auth tokens and other security measures which can be kind of a hassle for a normal user - especially if they aren’t the admin of the Jira account.

But since we are working with a Chrome extension we have access to browser wide cookies. This means, that if you have recently logged into Jira and Toggl we are automatically authenticated to use the API’S. If not, the user just have to log in again to re-authenticate. This procedure would not be possible with a normal web app since they can’t access these cookies.

How does it look?

The extension pop-up

Settings page of the extension

All in all

Chrome extensions are great tools for adding extra functionality to your browser or solve a specific issue. With Vue.js and the boilerplate it also got a lot easier to get started. With regards to my extension I think it turned out pretty well and it does exactly what I needed it to.

I created it as an Open-Source project on Github where developers are more than welcome to contribute with bug fixes and new features or just get inspired on how to build their own extension.

Chrome App Store: https://tinyurl.com/y4pj9por

Repository: https://github.com/simoneldevig/jira-toggl

I hope this short read will help you get started building your own extensions🤘

Top Web Application Developer

Top Web Application Developer

You can also contact a web application development company for your business but then why not to contact the best web application development company that can turn up your business and customer satisfaction ratio to sky touching heights.

Not long-ago internet came into existence and the world has never been the same ever since. The Internet made sure that people and business do evolve at a faster rate than ever and was never merciful to the slow ones. Because of this competition and availability of any business with few clicks made India one of the hubs as IT center. This trend of constantly updating has given rise to smartphones, smart machines, wearable gadgets and a lot more is yet to come in the upcoming years. In such time it is always a good idea to hire Web App Developer from India at your service. They are expert in developing not only websites but web applications as well.

We at HireFullStackDeveloperIndia, have a huge team of experienced developers that have grasped over different domains in front and back end development. You can hire web app developers in India from us with many advantages that you won’t get anywhere else in the industry.

Here is why we are the best option if you are looking forward to hiring web app developers in India:

  • Flexible hiring models available, as per your convenience and requirement
  • Maximum ROI, compared to any other company or team of developers.
  • We provide you with Source code Authorization meaning code written for you belong only to you. It cannot be used or copied anywhere else.
  • All of our developers are sound with agile development methodology, so you will be in a constant loop of suggestions, ideas, trends, and updates about your project.
  • Our developers are good with creating custom web applications as well; it guarantees you a better product without any compromise of non-existing functionalities.
  • You can save huge costing on infrastructure by utilizing our hire web app developer in India program.
  • Your hired developer or team will be easily accessible to your preferred mode of communication.
  • You get to exercise complete control over your team or individual that you hire.
  • We believe in Integrity and Transparency.
  • Our developers are highly creative and motivated to deliver excellence.


HireFullStackDeveloperIndia is a Web Application Development Company in India that is known worldwide for our Innovative guaranteed solutions. You can inquire with us about your project and we will be providing you multiple suitable developers that are the best fit for your requirements. You can evaluate them and select one or multiple whosoever deems fit to you. After this, all you have to do is provide your valuable input to the resource through sprint base project development until you get delivery of your project.

Our engagement model will also allow you to get our development team to your site location and proceed with development from your premises.