1

I'm working on a chrome extension (manifest v3) and would like to pass arguments to a file that I mentioned in the chrome.scripting.executeScripts. But, the documentation mentions that args is only valid if the func parameter is specified.

I found a similar question for Manifest v2 using chrome.tabs.executeScript which has a solution, but i'm not able to use a similar approach in manifest v3.

script with func (working)

// popup.js
chrome.scripting.executeScript({
    target: { tabId: tabId, allFrames: false },
    args: [eleID, type, offsetHeight + 10],
    func: scrollToTarget
});

function scrollToTarget(eleID, type, headerHeight = 40) {
   console.log({eleID, type, headerHeight);
}

NOT working

script with files

this is a similar approach to manifest v2 chrome.tabs.executeScript

// popup.js
chrome.scripting.executeScript({
    target: { tabId: tabId, allFrames: false },
    code: `var eleID = '${eleID}'; var type = '${type}'; var headerHeight = ${offsetHeight};`
}, function () {
    chrome.scripting.executeScript({
        target: { tabId: tabId, allFrames: false },
        files: ['./executeScript.js'],
    });
});

executeScrupt.js

scrollToTarget(eleID, type, headerHeight);

function scrollToTarget(eleID, type, headerHeight = 40) {
   console.log({eleID, type, headerHeight);
}

1 Answer 1

14

Option 1

executeScript in MV3 doesn't have code parameter so you need to rewrite it using func and set the arguments as properties of window (or its alias self), which is the same as a globally declared var for all practical purposes (assuming you don't use world: 'MAIN').

chrome.scripting.executeScript({
  target: {tabId},
  args: [{eleID, type, headerHeight: offsetHeight + 10}],
  func: vars => Object.assign(self, vars),
}, () => {
  chrome.scripting.executeScript({target: {tabId}, files: ['./executeScript.js']});
});

Option 2

Alternatively, you can make your injected file declare the functions without calling them:

// executeScript.js
function scrollToTarget(eleID, type, headerHeight = 40) {
  console.log(eleID, type, headerHeight);
}

Then you'll call the function after injecting the file:

chrome.scripting.executeScript({target: {tabId}, files: ['./executeScript.js']}, () => {
  chrome.scripting.executeScript({
    target: {tabId},
    args: [eleID, type, offsetHeight + 10],
    func: (...args) => scrollToTarget(...args),
  });
});
Sign up to request clarification or add additional context in comments.

2 Comments

Amazing answer! Should definitely go to the official doc.
The mental gimnastics you have to go through for a simple thing... thank you for the solution

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.