I am working on a Chrome Extension. This extension has to set a few window variables before the website JS loads. To set these window variables, I am injecting a script from the content-script into the document.
The issue I am facing is that the injected script is running after the website’s JS loads.
I need the injected script to run before the website JS so that the values are properly initialized.
Current Execution Order:
- Content Script -> Website JS -> Injected JS
Desired Execution Order:
- Content Script -> Website JS -> Injected JS
Is there any way that the injected script can be forced to run before the application JS?
I have no control over the Website JS, so the configuration will have to be on the extension.
manifest.json
{
"name": "script-injector",
"manifest_version": 3,
"version": "0.0.1",
"content_scripts": [
{
"matches": ["*://localhost:*/*", "*://127.0.0.1:*/*"],
"js": ["content.js"],
"run_at": "document_start"
}
],
"web_accessible_resources": [
{
"matches": ["<all_urls>"],
"resources": ["injected.js"]
}
]
}
content.js
console.log("CE: Content Script Loaded");
function injectScript() {
const script = document.createElement("script");
script.src = chrome.runtime.getURL("injected.js");
(document.head || document.documentElement).appendChild(script);
}
injectScript();
injected.js
console.log("CE: Injected Script Loaded");
window.someVar = true;
2
Answers
You need to listen for change in dom that adds the script, and remove it. I use this snippet to replace the script from
game.js
with my script.You can run the code in the context of the page (aka
MAIN
world) directly since Chrome 111."world": "MAIN"
for your content scriptYour new content.js:
Your new manifest.json:
Note that in this MAIN world your script can’t access
chrome
API of your extension, so if you need that you’ll need a second content script (without specifyingworld
) and then useCustomEvent
messaging, example.