Reputation: 5132
I have a chrome extension that calls a content script from a background script to insert HTML into a webpage.
When I call the content script (inject.js), I'd like to pass some parameters from the content script (eventpage.js), but am having some trouble doing so. I also don't want to use a solution that leverages chrome.storage or localstorage.
Manifest.json (relevant parts):
{
"manifest_version": 2,
"content_scripts": [
{
"matches": ["http://*/*"],
"js": ["inject.js"]
}
],
...
"background": {
"scripts": ["eventpage.js",...],
"persistent": false
},
}
Eventpage.js (background):
// Want to add the parameter here
chrome.tabs.executeScript(tabId, {
file: 'inject.js'
});
Inject.js (content):
(function() {
// Want to retrieve the parameter passed from eventpage.js here
})();
Upvotes: 5
Views: 4153
Reputation: 1142
With Manifest v3 the best way now is: userScripts (need to turn on developer mode in Chrome 120):
const dead = 'back';
chrome.userScripts.register([{
id: 'test',
matches: ['*://*/*'],
allFrames: true,
runAt: 'document_start',
world: 'MAIN',
js: [{code: `console.log('eval is ${dead}, baby!');`}]
}],
() => {
resolve(true);
});
The benefits: it is the fastest way to pass parameters in the content script which guarantees it will be executed faster than website's scripts.
Upvotes: 0
Reputation: 5118
Use messaging:
Eventpage.js
// Want to add the parameter here
var parameterToSend;
chrome.tabs.executeScript(tabId, {
file: 'inject.js'
}, function() {
chrome.tabs.sendMessage(tabId, {parameter: parameterToSend});
});
Inject.js
(function() {
// Want to retrieve the parameter passed from eventpage.js here
chrome.runtime.onMessage.addListener(function(message) {
var receivedParameter = message.parameter;
//use receivedParameter as you wish.
});
})();
Upvotes: 4
Reputation: 11
Solution you want to use is sometimes handy but it't not called content script and it's used in different situations that just inserting HTML on the page. You are trying to inject piece of JS directly into the website, whereas you specified inject.js file as content script.
Content script in WebExtensions standard means that the script has access to HTML of the webpage (minus some limitations such as iframes) and can modify it.
Consider changing content of your background script into:
chrome.tabs.query({active:true, lastFocusedWindow: true}, function(tabs){
if (tabs.length > 0) {
chrome.tabs.sendMessage(tabs[0].id, {
type:"message-type",
param: 'param'
});
}});
and in the content script add listener for the message retrieved from background
chrome.extension.onMessage.addListener(callback);
where callback
variable should be function that you want to run in inject.js file. This function may get a parameter in its signature and when it's executed it contains JS object passed as second parameter of chrome.tabs.sendMessage
function.
In this case it would be
var callback = function(data) {
// here in data.param you have your parameter
}
Also if you really need to use injection of the code, then you'll have to do two things:
Remove inject.js
from content_script part of your manifest.json
and add it into web_accessible_resources
part.
Read all the necessary info about injecting code Pass a parameter to a content script injected using chrome.tabs.executeScript()
Upvotes: 0