I’m working on a chrome extension that simply checks if a webpage is clicked and then adds 1 to a locally stored variable and displays it in the popup. However, the problem that I have is when I reload / install the extension it required for all existing tabs to be reloaded / opened again to actually count the clicks made on those webpages. If I don’t reload the website and click, it returns the error Uncaught (in promise) Error: Extension context invalidated.
Even if I reload the website and start clicking, it only is able to edit the badge 1 time no matter how many times I click the webpage. This issue only goes away when I open the popup as a new tab and inspect it for some reason. How can I fix these issues? (Side note: I’m not sure if I actually need to send a message to the service worker in the beginning and I marked with the comment “Probably Useless”. Do I actually need this?)
manifest.json:
{
"manifest_version": 3,
"version": "1.0",
"name": "Clicking game",
"description": "All clicks on Chrome add 1 to a counter in the popup",
"permissions": ["storage", "scripting", "activeTab"],
"background": {
"service_worker": "service-worker.js"
},
"action": {
"default_popup": "index.html",
"default_popup_open_in_tab": true
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content.js"]
}]
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Clicking Game</title>
</head>
<body>
<h1 id="counter">0</h1>
<script src="popup.js"></script>
</body>
</html>
content.js
document.onclick = log;
async function log() {
const response = await chrome.runtime.sendMessage({ type: "click" });
console.log(response);
const message = chrome.runtime.sendMessage({ type: "update", count: "5"});
console.log(message);
}
popup.js
// Grabbing the popup element to display cookies
const countElement = document.getElementById("counter");
// Updating the popup when it is opened
document.addEventListener('DOMContentLoaded', function() {
chrome.storage.local.get(['count'], function(result) {
if (result.count) {
countElement.textContent = result.count;
}
});
});
// Updating number of coookies when user clicks something
chrome.runtime.onMessage.addListener(
async (request, sender, sendResponse) => {
if (request.type === "update") {
let cookies = await chrome.runtime.sendMessage({ type: "returnAndAddToCookies" });
console.log("Update Message Received");
console.log("Updated Cookies: " + cookies);
chrome.storage.local.get(["count"]).then((result) => {
countElement.innerText = result.count;
console.log("Value is " + result.count);
});
}
}
)
service-worker.js
// Cookies Variable
let cookies = 0;
// Updating cookies if there is already a value in local storage
chrome.storage.local.get(["count"]).then((result) => {
if (result.count !== undefined) {
cookies = result.count;
}
console.log("Cookie is " + cookies);
});
// Updating the badge text on reloading / installing / restarting the extension
chrome.runtime.onStartup.addListener(() => {
chrome.action.setBadgeText({
text: cookies.toString()
});
});
chrome.runtime.onInstalled.addListener(() => {
chrome.action.setBadgeText({
text: cookies.toString()
});
});
// Function to activate the service worker, probably useless
chrome.runtime.onMessage.addListener(
function (request, sender, sendResponse) {
if (request.type === "click") {
console.log("Click request received");
sendResponse({farewell: "goodbye"});
// Returning the value of cookies for the service worker to display on the badge
}
}
)
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse, tab) => {
// Changing the badge text
if (request.type === "update") {
await chrome.action.setBadgeText({
text: (cookies + 1).toString()
})
} else if (request.type === "returnAndAddToCookies") {
cookies++;
chrome.storage.local.set({ count: cookies }).then(() => {
console.log("Updated Value");
});
sendResponse(cookies);
}
})
I’ve tried manually injecting the scripts into all tabs when the extension is installed / reloaded / updated etc. (Maybe this works? If so, could someone send a code snippet?) I’ve tried removing the console logs to solve the second problem.