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

Problem encountered when attempting to add elements to an array within a nested

When running this code, everything works correctly except for the array pushing. After checking the console.log(notificationdata), I noticed that notification data gets its values updated correctly. However, when I check console.log(notifications), I see ...

Guide to fetching external data with Next.js and importing the component into a different file

I have implemented the following code in my pages/github file, and when I navigate to localhost:3000/github, the code runs successfully and returns JSON data. function GithubAPI(props) { // Display posts... return (<div>{props.data.name}</div& ...

Retrieving information within a Vue component

I am struggling to access some data I have bound to a component without success. How can I achieve this? Below is my component: export default { name: 'component-vallingby', data() { return { } }, created() {}, methods: {} } And h ...

Using Jquery Mobile to make an AJAX POST request with XML

Is it possible to use this code for XML parsing? I have successfully parsed using JSON, but there is no response from the web service. This is the status of the webservice: http/1.1 405 method not allowed 113ms $j.ajax({ type: "GET", async: false, ...

Exploring ways to repeatedly collapse rows using HTML, CSS, and JavaScript

GOAL: I want to freeze the header, freeze the first column, and be able to collapse rows multiple times. CURRENT PROGRESS: I have achieved freezing the header, first column, but can only collapse rows once. MY CODE SNIPPET: </head> <body> &l ...

Utilizing multiple instances of date picker components in React.js

Is there a way to update the date on react-datepicker when using multiple instances of the datepicker component? I have encountered an issue with this. Here is the code for the Date picker Component: <DatePicker selected={this.state.from} onChange ...

Comparing the functions of useMemo and the combination of useEffect with useState

Is there a benefit in utilizing the useMemo hook instead of using a combination of useEffect and useState for a complex function call? Here are two custom hooks that seem to function similarly, with the only difference being that useMemo initially returns ...

Is it possible to fire a Socket.io emit with a scroll event?

Can you trigger an emit on a gesture or scroll event, similar to how it works on a click event? I'm trying to create something like this: https://www.youtube.com/watch?time_continue=38&v=tPxjxS198vE Instead of relying on a click, I would like to ...

Guide on implementing Regular Expressions in Directives for validation in Angular 8

Managing 8 different angular applications poses its unique challenges. In one of the applications, there is a directive specifically designed for validating YouTube and Vimeo URLs using regular expressions. Unfortunately, once the RegExp is declared, ther ...

Is there a way to insert a secured page right before accessing the dashboard?

I am trying to create a locked page that will display a message when users access the web app from a mobile device and load a mobile layout page displaying a message like mobile is not supported. I was considering using document.addEventListener('DOMC ...

Utilizing JQuery for real-time total updates

When a new div is created by clicking a button, I want to dynamically maintain an order system where the first div is labeled as 1 of 1, then as more divs are added it should change to 1 of 2, and so on. If a div is deleted, the numbering should reset back ...

Having trouble uploading an image to firebase storage as I continuously encounter the error message: Unable to access property 'name' of undefined

Hey there, I'm currently facing an issue while trying to upload an image to Firebase storage. Despite following all the instructions on the official Firebase site, I'm stuck trying to resolve this error: Uncaught TypeError: Cannot read property ...

Having trouble determining the dimensions of a newly added element

I am using jQuery to dynamically add an image but I am unable to retrieve its dimensions (width and height). Below is the snippet of code from my HTML file: <input type="checkbox" id="RocketElement" data-id="1"> And here is the JavaScript/jQuery c ...

Make object calculations easy with the power of JavaScript

I've stored a JSON object in a variable and I'm performing calculations based on its properties. However, the current method of calculation seems lengthy, especially as the data grows larger. I'm searching for a more concise approach to per ...

Include a new variable in a JavaScript email template

Is there a way to include the variable bob in the body of an email? var bob; function sendMail() { var link = "mailto:YourEmailHere" + "?cc=" + "&subject=App Build Link Buit With MWFPRO's App Build Tool" + "&body=Hi ...

What is the method for including word boundaries in a regex constructor?

export enum TOKENS { CLASS = 1, METHOD, FUNCTION, CONSTRUCTOR, INT, BOOLEAN, CHAR, VOID, VAR, STATIC, FIELD, LET, DO, IF, ELSE, WHILE, RETURN, TRUE, FALSE, NULL, THIS } setTokenPatterns() { let tokenString: s ...

xhttp.load path for server-side module

I'm currently working on developing a node package and in my JavaScript code, I have the following: const calcHtml = './calc.html'; const xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function () { if (this.readyState == 4) { ...

Attempting to automatically invoke the API every minute, rather than relying on the user to reload the page

I currently have fetchCoins() in my mounted() function, which calls the API whenever a user refreshes. My goal is to call the API once, store the data in local storage, and then retrieve the data every minute. methods: { async fetchCoins() { con ...

What might be causing my mongoose query to take so long? (~30 seconds)

I've encountered a problem with a route in my application. This specific route is supposed to fetch an array of offers that a user has created on the app by providing the user's id. Initially, when the user has only a few offers, the query execut ...

Is it possible to conceal the text specifically inside a textarea, rather than just hiding the entire textarea itself?

Is it possible to have a button next to the textarea that allows you to hide and unhide the text inside the textarea by clicking on it? ...