Skip to content

Instantly share code, notes, and snippets.

@danharper
Last active August 23, 2024 01:26
Show Gist options
  • Save danharper/8364399 to your computer and use it in GitHub Desktop.
Save danharper/8364399 to your computer and use it in GitHub Desktop.
Bare minimum Chrome extension to inject a JS file into the given page when you click on the browser action icon. The script then inserts a new div into the DOM.
// this is the background code...
// listen for our browerAction to be clicked
chrome.browserAction.onClicked.addListener(function (tab) {
// for the current tab, inject the "inject.js" file & execute it
chrome.tabs.executeScript(tab.ib, {
file: 'inject.js'
});
});
// this is the code which will be injected into a given page...
(function() {
// just place a div at top right
var div = document.createElement('div');
div.style.position = 'fixed';
div.style.top = 0;
div.style.right = 0;
div.textContent = 'Injected!';
document.body.appendChild(div);
alert('inserted self... giggity');
})();
{
"name": "Injecta",
"version": "0.0.1",
"manifest_version": 2,
"description": "Injecting stuff",
"homepage_url": "http://danharper.me",
"background": {
"scripts": [
"background.js"
],
"persistent": true
},
"browser_action": {
"default_title": "Inject!"
},
"permissions": [
"https://*/*",
"http://*/*",
"tabs"
]
}
@wtorcaso
Copy link

This is a newbie question: When I hear "Chrome Extension", I think of code that the user has to agree to run, and that can be removed by the user at any time. Is this like that, or is "extension" an overloaded word in this context, and means something else?

Thanks!

@antony
Copy link

antony commented Jul 27, 2019

@wtorcaso you are correct in your assessment - a Chrome Extension is a user installable extension to the Chrome or Chromium browser.

@waqas-mehmood-pk
Copy link

@dunklesToast I have tried your suggested method but failed to execute the script of injected file.
Here is what I have tried.

First Approach:

chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
    chrome.tabs.executeScript(tabs.id, {
         code: "document.body.appendChild(document.createElement('script')).src = 'https://test.com/js/site.com.js'";
    });
});

image

In this approach .js file injected but script of that file could not access/run.

Second Approach:

chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
    chrome.tabs.executeScript({file: "https://test.com/js/site.com.js"});
});

Third Approach:

chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
    chrome.tabs.executeScript({
       tabId: tabs.id,
       file: "https://test.com/js/site.com.js"
    });
});

In both 2nd and 3rd approaches file not injected.

@Veverke
Copy link

Veverke commented May 6, 2020

According to the docs, if the goal is to inject scripts into tabs, I think declarative injection is the simplest solution. In the manifest, add

	"content_scripts": [
		{
		 "matches": ["https://*/*","http://*/*"],
		 "js": ["myJsFile.js"]
		}
	],

The above injects myJsFile.js into every tab opened in the browser.
And make sure you enabled 'activeTab' in the permissions setting.

@qtcoder999
Copy link

you are awesome !!!!!!!! Thank you man!!!!

@AnthonyisMedia
Copy link

AnthonyisMedia commented Jun 17, 2020

How would you remove the div by clicking the extension icon?

This method has worked great for adding a fixed menu div on top of a webpage but it would be awesome if I could delete/remove what I added and reset the page to the way it was. All without refreshing the page of course.

I figured making these changes to the background script and adding an ID to my div for deletion would work but the code doesn't seem to find the div. So I can't remove the div I added.

`

// this is the background code...

var ToggleExtension = false;

// listen for our browerAction to be clicked

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

// for the current tab, inject the "inject.js" file & execute it	
if (ToggleExtension == false){

   chrome.tabs.executeScript(tab.ib, { file: 'Inject.js' });
   ToggleExtension = true;

} else if (ToggleExtension == true){

   var MyDiv = document.getElementById(MyDiv);
   MyDiv.parentNode.removeChild(MyDiv);
   ToggleExtension = false;

}
});`

@ShamsherNawaz
Copy link

Amazing..... Thanks man

File injected in any page when I click the icon. What if I want to inject file automaticaly after page load of a specific page/site.

@rrakso
Copy link

rrakso commented Sep 9, 2020

Hi @ShamsherNawaz!
Look at this comment (here is the reference).

I added also to this solution this piece of code

window.addEventListener("load", () => {
  // Here the rest of the code executed when page is fully loaded
});

@bbsmithy
Copy link

thanks for this! is it easy to make this work on specific urls without clicking the extension?

great work!

If you add this to your commands section in manifest.json

"commands":{
    "_execute_browser_action": {
      "suggested_key": {
        "default": "Ctrl+Shift+F",
        "mac": "MacCtrl+Shift+F"
      }
    }
  }

You can open the browser action with a keyboard command, which will trigger the onClick event

@Randomblock1
Copy link

Thanks so much!! For anyone trying to inject JavaScript and run a function that already exists within the page:

inject.js

(function() {

        location.href="javascript:someExistingFunctionInPage(); void 0";

})();

from StackOverflow, because everything is

@ac-0rn
Copy link

ac-0rn commented Jan 19, 2021

Exactly what I was looking for, thanks!

@njerschow
Copy link

This is exactly what I needed, thanks!

@KyraCoding
Copy link

I know people have already said this, but THIS IS EXACTLY WHAT I NEED! Thanks!

@tsikerdekis
Copy link

Anyone knows if this solution works for V3?

@siddharthcpatel
Copy link

siddharthcpatel commented May 23, 2021

Anyone knows if this solution works for V3?

You have to make a few changes:

browserAction -> action

tabs -> scripting (You need to change permissions in manifest.json too.)

file: 'inject.js' -> files: ['inject.js'] // should be array

You also need to add another required parameter called target where you add files.
target: { tabId: tabId // should be integer }

Checkout chrome's official migration checklist.

EDIT: Updated code

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

	// for the current tab, inject the "inject.js" file & execute it	
       chrome.scripting.executeScript(tab.ib, {
                target: {tabId: tabId} // required in MV3
		files: ['inject.js']	
       });
});

@vineet-sinha
Copy link

tab.ib is not a parameter, so the updated code should be:

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

	// for the current tab, inject the "inject.js" file & execute it	
       chrome.scripting.executeScript({
                target: {tabId: tab.id},
		files: ['inject.js']	
       });
});

@asmirbe
Copy link

asmirbe commented Jul 21, 2021

any proper way to disable the extension then remove the injected content clicking the extension icon again ??
Ty guys

@600drive
Copy link

URL: testsite.com/files/script.js

chrome.browserAction.onClicked.addListener(function (tab) {
// for the current tab, inject the "www.site.com/system/trail/inject.js" file & execute it
chrome.tabs.executeScript(tab.ib, {
URL: www.site.com/system/trail/inject.js
//file: 'inject.js'
});
});

@600drive
Copy link

no work

@600drive
Copy link

According to the docs, if the goal is to inject scripts into tabs, I think declarative injection is the simplest solution. In the manifest, add

	"content_scripts": [
		{
		 "matches": ["https://*/*","http://*/*"],
		 "js": ["myJsFile.js"]
		}
	],

The above injects myJsFile.js into every tab opened in the browser.
And make sure you enabled 'activeTab' in the permissions setting.

myJsFile.js if i want store on domain how can i do ? thanks you for your reply

Copy link

ghost commented Sep 6, 2021

Thanks xD

@pablodz
Copy link

pablodz commented Nov 7, 2021

Thanks mate

@enniosousa
Copy link

Thank you very much!

@nimatalebi
Copy link

nimatalebi commented Feb 7, 2022

It does not work if you do not add "web_accessible_resources": ["script.js"] to manifast.json

@Suraj-bhan
Copy link

hey
@danharper I want to inject some elements on page load(when some specific element is loaded on the page) in some particular webpage in some specific container without clicking the extension icon, is there any way I can do that?

@arthurbolsoni
Copy link

arthurbolsoni commented Oct 6, 2022

hey @danharper I want to inject some elements on page load(when some specific element is loaded on the page) in some particular webpage in some specific container without clicking the extension icon, is there any way I can do that?

i trying doing it with chrome.scripting.executeScript but until now i have doing this way:

manifest v3

  "content_scripts": [
      {
          "matches": [
              "https://*.twitch.tv/*"
          ],
          "run_at": "document_start",
          "js": [
              "content-script.js"
          ]
      }
  ],
  "web_accessible_resources": [
      {
          "resources": [
              "app/bundle.js"
          ],
          "matches": [
              "<all_urls>"
          ]
      }
  ]

content-script.js

function init(items) {
  var s = document.createElement("script");
  s.src = chrome.runtime.getURL("app/bundle.js");
  s.onload = function () {
    this.remove();
  };

  (document.head || document.documentElement).appendChild(s);

  window.addEventListener("message", (event) => {
    if (event.data.type && event.data.type == "init") {
      window.postMessage(
        {
          type: "setInit",
          value: chrome.runtime.getURL("app"),
        },
        "*",
      );
    }
    if (event.data.type && event.data.type == "getSetting") {
      window.postMessage(
        {
          type: "setSetting",
          value: items,
        },
        "*",
      );
    }
  });
}

chrome.storage.local.get(["whiteList", "toggleProxy", "proxyUrl"], (items) => init(items));

so, the bundle is loaded when the page is opened

i think is posible do it with less lines using chrome.scripting

@murat1999
Copy link

I have a question regarding that. I know how to inject a js file when some action is triggered, but how can I inject a certain function in the js file? Like in the above example we are injecting js/inject.js file but I want to inject or execute a certain function in the background.js from js/inject.js file when I click the button in the popup.

@arthurbolsoni
Copy link

arthurbolsoni commented Dec 15, 2022

you will execute all the file as a function.

( () => {

//code

})()

I wasted a lot of time trying to find a way to pass parameter to this file. until you find the events.

You can run the file and tell it which function to activate using events: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

@murat1999
Copy link

murat1999 commented Dec 15, 2022

you will execute all the file as a function.

( () => {

//code

})()

I wasted a lot of time trying to find a way to pass parameter to this file. until you find the events.

You can run the file and tell it which function to activate using events: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

My goal is to run certain function say in js/inject.js file in all tabs in my chrome. Does by iterating all tabs and executing this js file on each tab give me a correct result? And when I run and tell which function to activate using events does it run on each tab individually?
My function is retrieving DOM, and other tab info (user agent, cookies etc) from each tab. And I am wondering if it works for each tab when I run js/inject.js file

@Jumpjetjumpjet
Copy link

Jumpjetjumpjet commented Jan 19, 2023

Hi Good day
I have a plugin whose manifest version is 2 and I updated it to 3 and I don't know if it is correct or not but it gives an error in the background that the document is not defined.
My plugin files:
manifest.json
background.js
pics.png
content.js
I will put the code

//manifest.json v2
{
"manifest_version": 2,
"name": "bot",
"version": "5.07",
"description":"Telegeram : @ali_barati86",
"content_scripts" : [{
"matches" : ["http:///","https:///"],
"js" : ["background.js"]
}],

"browser_action": {
"default_icon": "crash.png",
"default_title": "Crash Bot"
},
"web_accessible_resources": ["content.js"],
"permissions": [
"https:///",
"http:///",
"tabs"
]
}

I updated the above codes to version three
//manifest.json v3

{
"manifest_version": 3,
"name": "bot",
"version": "5.07",
"description":"Telegeram : @ali_barati86",
"permissions" : [
"activeTab",
"scripting",
"tabs"
],

"host_permissions": [
"http:///",
"https:///",
"<all_urls>"
],
"background": {
"service_worker": "background.js",
"type": "module"
},
"icons":{
"16": "crash.png",
"32": "crash.png",
"48": "crash.png",
"128": "crash.png"
},
"action": {
"default_title": "crash bot",
"default_icon": "crash.png"
},
"web_accessible_resources": [
{
"resources": [
"content.js"
],
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'",
"sandbox": "sandbox allow-scripts; script-src 'self' 'https://apis.google.com/' 'https://www.gstatic.com/' 'https://.firebaseio.com' 'https://www.googleapis.com' 'https://ajax.googleapis.com'; object-src 'self'"
},
"matches": [
"http://
/",
"https://
/*",
"<all_urls>"
]
}
]
}

//background.js

var s = document.createElement('script');
s.src = chrome.extension.getURL("content.js");
s.onload = function() {
    this.parentNode.removeChild(this);
};

(document.head||document.documentElement).appendChild(s);


Please help me, I'm waiting, send me an email or a telegram
[email protected]
Telegram: @ali_barati86
If you want to tell me to check the plugin, please solve my problem, thank you
Plugin download link:
https://uupload.ir/view/extension_lst.zip/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment