Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Store data from background.js into the vuex store

So I am trying to use the vuex store into my chrome extension. My entire project is based out of VueJs.

I have a popup which opens up after I click the extension button. I am also using background.js to listen to url of the current tab using the chrome API.

Now, all I want to do is to store this url from the background.js to the store, which I can then use to get the data into my popup.html and render the url in it.

Now I have no clue how can I use the vuex store in my plugin.

P.S. I am fairly new to chrome extension development and some code references or guidance can be helpful :)

like image 612
Mohit Kamal Avatar asked Jun 29 '19 04:06

Mohit Kamal


1 Answers

You can use this plugin for Vuex: vuex-webextensions

An example of how to use this to do what you want is:

Inside the background script for your extension import:

  1. Vue
  2. Vuex
  3. vuex-webextentions
  4. webextension-polyfill

I recommend using webextension-polyfill because you can use chrome's callback style APIs as promise APIs (giving you the option to either use .then() or async/await.

Also import any actions, mutations, getters etc that you're using in your app's Vuex store.

// background.js

import Vue from 'vue';
import Vuex from 'vuex';
import VuexWebExtensions from 'vuex-webextensions';

import * as actions from './store/actions';
import * as getters from './store/getters';
import mutations from './store/mutations';

global.browser = require('webextension-polyfill');

Vue.use(Vuex);

const store = new Vuex.Store({
  plugins: [VuexWebExtensions({
    persistentStates: ['currentTabUrl'],
  })],
  state: {
    currentTabUrl: '',
  },
  getters,
  mutations,
  actions,
});

/* if you want to get the active tab URL anytime someone clicks your extension icon,
 * you'll need to listen for the onClicked event on browserAction.
 * The onClicked event handler receives an optional parameter which is the current tab.
 * You'll also need to ensure you've set "tabs" permission in your manifest.json

https://developer.chrome.com/extensions/browserAction#event-onClicked
*/

// Assuming you've used the webextension-polyfill as I have:

browser.browserAction.onClicked.addListener((tab) => {
  store.dispatch('nameOfYourActionToUpdateStore', tab.url)
});

// or without using the webextension-polyfill

chrome.browserAction.onClicked.addListener((tab) => {
  store.dispatch('nameOfYourActionToUpdateStore', tab.url)
});

export default store;

Now, for your popup you may have an instance of a Vue app + Vuex store. For example:

// popup.js

import Vue from 'vue';
import Vuex from 'vuex';
import VuexWebExtensions from 'vuex-webextensions';
import App from './App';

// import any actions, mutations, getters you might have
import * as actions from './actions';
import * as getters from './getters';
import mutations from './mutations';


// Assuming you've used the webextension-polyfill as I have:
global.browser = require('webextension-polyfill');

// Assuming you've used the webextension-polyfill as I have:
Vue.prototype.$browser = global.browser;

Vue.use(Vuex);

const store = new Vuex.Store({
  plugins: [VuexWebExtensions({
    persistentStates: ['currentTabUrl'],
  })],
  state: {
    currentTabUrl: '',
  },
  getters,
  mutations,
  actions,
});

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

export default store;

In our example, the App.vue may look something like:

// App.vue

<template>
 <p> {{ currentTabUrl }} </p>
</template>

<script>
import { mapState } from 'vuex'

export default {
  updated() {
    console.log(this.$store.state.currentTabUrl);
  },
  data() {
    return {};
  },
  computed: {
    ...mapState([
      'currentTabUrl'
    ])
  },
};
</script>

<style lang="scss" scoped>
p {
  font-size: 20px;
}
</style>

Essentially, now your extension has two instances of a Vuex store: 1 in background.js and 1 in popup.js. The Vuex-webextensions plugin uses the chrome.storage API to keep the two stores in sync. It treats the background.js store as Master and all other instances as copies of this master.

One thing to note is that you cannot inspect this storage space in regular chrome devtools. In order to see the contents of this storage space you will need to install the following extension:

Storage Area Explorer

I hope that helps. Let me know if anything needs further explaining.

like image 62
zshnr Avatar answered Nov 12 '22 01:11

zshnr