Stuart P. Bentley
Stuart P. Bentley

Reputation: 10755

How do I make it so my Chrome extension will only inject a script once?

I'm using programmatic injection to inject my extension's code into a page only when the browser action is clicked.

This is what I have on my extension's event page (per the example in the documentation):

chrome.browserAction.onClicked.addListener(function callback(tab){
  chrome.tabs.executeScript(null, {file: "content-script.js"});
});

However, the way this works, the script is injected every time the button is clicked.

How can I change it so that the script is not injected on subsequent button presses - so that it is inserted only the first time the button is clicked on that page?

Upvotes: 5

Views: 4393

Answers (3)

RyanMac22
RyanMac22

Reputation: 1

I know this is an older question but I encountered the issue now that Manifest V3 is out and persistent background pages have been replaced with service workers. I figured I'd give what I used as a solution in case anyone else needs it. Code must be executed within the global context of the content script. Anytime it tries to inject it again, the relevant code will only be executed if the global variable is not defined.

if (typeof hasBeenExecuted === 'undefined') {
    // Code that needs to execute only once goes here
}
var hasBeenExecuted = true;

Hopefully this is helpful for someone else who comes across the question.

Upvotes: 0

Tom
Tom

Reputation: 794

Put a global variable in your contentscript to judge if the contentscript has been executed.

if (something) { return; }

Upvotes: 8

user2723564
user2723564

Reputation: 21

One way I can think of right now (easy and simple) is to use html5webstorage. Since you are running this code from your background or popup page it will be ok.

if(!localStorage.getItem("isAlreadyInjected")){
   localStorage['isAlreadyInjected'] = "true";
   chrome.browserAction.onClicked.addListener(function callback(tab){chrome.tabs.executeScript(null, {file: "content-script.js"});});}

So, the very first time when storage value "isAlreadyInjected" does not exist, the listener will be added. Afterwards, even when the browser closes and opens again this value will remain stored and so the listener will not be added to your extension.

UPDATE

As your background page loads only once at the beginning, it can keep variable that is not re-initialized with the browser action click. So you can use that variable to do your job!

background.js

var isAlreadyInjected =false;
function isInjected(){

if(!isAlreadyInjected ){
    isAlreadyInjected=true;
    return false;
 }
 else
    return true;
}

popup.js

var bgpage=chrome.extension.getBackgroundPage();
 if(!bgpage.isInjected()){
    chrome.browserAction.onClicked.addListener(function callback(tab) {chrome.tabs.executeScript(null, {file: "content-script.js"});});
}

or

var bgpage=chrome.extension.getBackgroundPage();
  chrome.browserAction.onClicked.addListener(function callback(tab) { 
 if(!bgpage.isInjected()){
    chrome.tabs.executeScript(null, {file: "content-script.js"});
}});

Upvotes: 2

Related Questions