Tips for enabling/disabling a Chrome extension through the utilization of local storage in the background page

Even after reading numerous answers on similar questions, I am still facing some difficulties. My goal is to allow the user to disable my chrome extension by simply clicking on the icon at any time. The extension is designed to run once on every page load, so when the icon is clicked, it should prevent the code from running on the next page load. When the icon is clicked, it should visually change color to indicate whether it's active or inactive. This aspect of the code is functioning as intended, but there seems to be an issue with updating a localStorage variable to reflect the status of the extension. Despite setting the storage variable to "off" when the icon is clicked, the content script continues to execute on each page load. Upon checking the console, the localStorage variable consistently displays "on." What could be causing this behavior?

P.S. I have also verified that the content script is not always resetting the storage variable to "on," in case it was being reset upon reloading the page.

Manifest.json

{
"manifest_version": 2,
"name": "My Extension",
"version": "0.1",

"icons":
{
 "128": "128.png",
 "48": "48.png",
 "16": "16.png"
 },

"content_scripts": [
{
"matches": [
    "<all_urls>"
       ],
"js": ["jquery-3.1.1.min.js", "content.js"]
}
],

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

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

"permissions": ["tabs", "storage"],

"web_accessible_resources": [
    "spritesheet.png"
 ]

}

Background Page

chrome.browserAction.onClicked.addListener(function(tab) {

  //if on, turn off
  if (localStorage.onoff == "on") {

    chrome.browserAction.setIcon({path:{"16": "16grey.png", "48": "48grey.png","128": "128grey.png"}});
    localStorage.onoff = "off";

   //if off, turn on
   } else {

    chrome.browserAction.setIcon({path:{"16": "16.png", "48": "48.png","128": "128.png"}});
    localStorage.onoff = "on";
   }


});

Content script

if (!localStorage.onoff) {
 localStorage.onoff = "on";
}


if (localStorage.onoff == "on") {
  //execute the extension
}

Answer №1

Utilizing chrome.storage.local

When transferring data between your background script and content script, it is not recommended to use localStorage. The content script's access to the page/domain's localStorage should remain specific to the injected page for effective functionality. In such cases where non-Chrome API functionalities are required, utilizing chrome.storage.local is more appropriate.

To ensure that your content script can read a set data value from the background script before loading, utilize chrome.storage.local.

The data can be set using chrome.storage.local.set():

chrome.storage.local.set({
    onOff: 'on'
}, function(){
    console.log('Data saved');
});

Retrieve the data using chrome.storage.local.get():

chrome.storage.local.get({
    onOff: 'off'
}, function(data) {
    if(data.onOff === 'on') {
        //Implement your code
    }
});

Additional Considerations

Loading jQuery:
Loading jQuery on every single page may impact performance as it adds unnecessary weight to each page load. Given that extensions cater to specific browsers, consider implementing functions in vanilla JavaScript instead of relying on jQuery to optimize user experience.

Injecting Content Script in <all_urls>:
It is advisable to assess the necessity of injecting your content script into all URLs visited by the user. Limiting the injection to relevant URLs can improve efficiency. Use tabs.executeScript() to inject scripts only when the extension is active.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Troubleshooting jQuery: Unable to refresh the webpage

I have a PHP page that contains a form, checkboxes, and a submit button. I added an if statement to execute a PHP script I created when the button is clicked, which deletes certain values from the selected rows. The button functions properly and changes s ...

Guide on managing firebase and webrtc tasks within a client-side component using Next.js 13

I developed a Next.js 13 application to share the camera feed using WebRTC and Firestore. Below is my page.tsx file where I am facing some challenges. I can't make this server-side because I'm using React hooks, and moving it to the client side i ...

Leveraging JavaScript to create a horizontal divider

Just a quick question - how can I create a horizontal line in Javascript that has the same customization options as the HTML <hr> tag? I need to be able to specify the color and thickness of the line. I am working on a website where I have to includ ...

In AngularJs, use ng repeat and ng switch to dynamically generate and display tables

I need help rendering a table with two columns using angularjs directives. <table> <tr ng-repeat="message in messages" > <td ng-switch-on="message.network" ng-switch when="twitter" ng-controller="TweetController"> <span> ...

Automatically omitting a selector that mimics a switch

After conducting thorough research, I discovered a variety of solutions using jQuery and Vanilla. While one answer perfectly addressed my issue, it failed to integrate effectively with the rest of my code. So, I decided to modify the code from this Stack O ...

Navigate through JSON data to uncover the tree structure path

In my project, I am working on creating a treeview user interface using the JSON provided below. I have included properties such as node-id and parentId to keep track of the current expanded structure. Next, I am considering adding a breadcrumb UI compone ...

The mapStateToProps function is returning an undefined value

import React, { Component, Fragment } from "react"; import { connect } from "react-redux"; import { login, logout } from "./redux/actions/accounts"; import Home from "./Home"; import Login from "./Login"; class ToggleButton extends Component { render() ...

Including a hyperlink in VUE Bootstrap for seamless user navigation

Why does this always drive me crazy? I'm determined to include an external link () and an image(enter image description here) on my portfolio page within the title of the project. main.js { id: 18, url: 'single-portfolio. ...

Step-by-Step Guide on Retrieving Filtered Data using React Context API

Currently, I am in the process of developing a dashboard application using React.js, React Context API, and ApexCharts. The app will visualize a 1000-length JSON data on 7-8 different charts, along with 6-7 variable filters. Overview of the App Structure: ...

Tips for incorporating user access control logic into a lazy-loaded Angular Monorepo application without embedding the logic in the main application

In our current project, we are developing an Angular application utilizing the Angular monorepo structure. This setup includes a parent application and several children applications, with the parent application located in the `app` folder and the children ...

Loading images in advance with AJAX for enhanced AJAX performance

My website is structured in a sequential manner, where page1.html leads to page2.html and so on. I am looking to preload some images from the third page onto the second page. After searching, I came across this amazing code snippet: $.ajax({ url ...

Sharing data from AJAX calls in Vue using vue-resource

After using Vue resource, I'm attempting to create an AJAX call that is based on the data received from a prior AJAX call. I have successfully bound the data fetched from /me to the userDetails prop. However, when trying to pass userDetails.id into t ...

JavaScript Slider for Color Selection

In my slider, I have added a .images class along with buttons for previous and next. To set the colors, I have used JavaScript to define an array like this: let colors = ['red', 'green',]; Currently, clicking the next-button displays ...

How to update the selected autocomplete item in Vue using programming techniques?

Although I am still learning Vue, consider the following scenario: <v-autocomplete v-model="defaultUser" :hint="`User: ${defaultUser.username}`" :items="users" :item-text="item =>`${item.firstName} - $ ...

Having trouble retrieving information from ajax to php

I'm struggling to understand why this code is not functioning as expected: idcurso= res[0]; idusuario= res[1]; semana= res[2]; fecha=res[3]; asistencia= true; $.ajax({ type: "POST", url: '/test/7/tomarasistencia.php', data: { ...

Sending information to a jQuery UI Dialog

I'm currently working on an ASP.Net MVC website where I display booking information from a database query in a table. Each row includes an ActionLink to cancel the booking based on its unique BookingId. Here's an example of how it looks: My book ...

Transferring canvas element via socket with JS stack size limit

I'm encountering an issue where I need to transfer a canvas element over sockets using socket.io and Node.js. The code snippet below illustrates my approach: var myCanvas = document.getElementById("myCanvas"); var ctx = myCanvas.getContext("2d"); // ...

Issue with the back-to-top button arises when smooth-scrolling feature is activated

This Back To Top Button code that I discovered online is quite effective on my website. // Defining a variable for the button element. const scrollToTopButton = document.getElementById('js-top'); // Creating a function to display our scroll-to- ...

What is the most effective method for the server to communicate with a web client through message delivery?

If you have any links to articles related to this topic, please share them as I may not know the exact terminology to search for. I am interested in understanding how a web application can facilitate server-to-client communications. The internet was not o ...

Communicating between PHP chat client and server

Currently, I am developing a basic PHP web chat application that interacts with a MySQL database. The communication is facilitated through AJAX requests - when a user posts a message, it gets saved in the database. function sendData(){ var textData = $(& ...