I want to add a side panel to all my tabs which can be done with the manifest config below. However, doing so prevents the chrome.action.onClicked listener events from being detected. As a result, I can't call chrome.tabs.captureVisibleTab because of a permission error (it believes no user has interacted and gives the error "Either the '<all_urls>' or 'activeTab' permission is required" unless it's nested within chrome.action.onClicked listener. I don't want to use a popup or contextMenu unless absolutely needed.
How do I open the side panel with the action button for all tabs and then capture a screenshot based on a click with a content script?
Any help would be greatly appreciated.
Thanks!
manifest.json:
{
"version": "1.0.0",
"manifest_version": 3,
"action": {
"default_title": "My app recording - click to get started"
},
"background": {
"service_worker": "service_worker.js"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
],
"permissions": ["storage", "<all_urls>", "activeTab", "windows", "sidePanel"],
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'; img-src *;"
},
"icons": {
"16": "logo16.png",
"48": "logo48.png",
"128": "logo128.png"
},
"side_panel": {
"default_path": "sidepanel.html"
}
}
service_worker.js
const messageListener = (request, sender, sendResponse) => {
(async () => {
try {
if (request.type === "register-click") {
chrome.tabs.captureVisibleTab(async (dataUrl) => {
if (chrome.runtime.lastError && !dataUrl) {
console.error("Error capturing tab:", chrome.runtime.lastError);
} else {
console.log("dataUrl", dataUrl);
}
// ... do things with screenshot
});
}
sendResponse({ status: "received" });
} catch (error) {
console.log(error);
sendResponse({ status: "error", error });
}
})();
return true;
};
chrome.sidePanel
.setPanelBehavior({ openPanelOnActionClick: true })
.catch((error) => console.error(error));
chrome.action.onClicked.addListener(async (tab) => {
await chrome.runtime.onMessage.addListener(messageListener);
});