The issue:
I have a chrome extension that fetches some data when the user clicks a hotkey. The fetch happens in the background. However, if you open and close the popup, the fetch for that request never returns. I can see it go out in the network requests, but it just sits as pending. If you don't open and close the popup, it returns just fine.
Here are the relevant files/code:
Manifest file:
{
"manifest_version": 3,
"name": "Simple hotkey extension",
"version": "0.0.1",
"description": "Extension",
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
"action": {
"default_icon": {
"16": "icon.png",
"24": "icon.png",
"32": "icon.png"
},
"default_title": "Title",
"default_popup": "popup/popup.html"
},
"host_permissions": ["<all_urls>"],
"options_page": "options.html",
"permissions": [
"activeTab",
"contentSettings",
"contextMenus",
"scripting",
"storage",
"unlimitedStorage"
],
"background": {
"persistent": true,
"service_worker": "background.js"
}
}
Relevant part of background:
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.message === 'SEND_URL_DETAIL') {
const {url, website} = request;
fetchPageData(url, website)
.then(data => {
console.log(data, 'this is my data');
appendStoredClicks(data);
})
.catch(err => console.log(err));
// It's unclear if Chrome extension development actually needs a response.
sendResponse({farewell: 'goodbye'});
}
});
The API request from the utils folder:
export async function fetchPageData(
url: string,
website: string,
): Promise<any> {
const wrappedUrl = `http://localhost:8080/fetch/website?url=${url}&website=${website}`;
console.log('About to fetch');
const res = await fetch(wrappedUrl);
if (!res.ok) {
throw new Error('Page not found');
}
const data = await res.json();
console.log('Data received', data);
return {...data, url};
}
Update based on @wOxxOm's comment I use react so popup.html is compiled by npm. Here's the current output.
Popup.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hotkey Extension</title>
<meta name="viewport" content="width=device-width, initial-scale=1"></head>
<body>
<script src="popup.js"></script>
</body>
</html>
These are the only places where I can see onMessage called.
Popup.js only has 3 lines of code that use Chrome:
chrome.action.setBadgeText
chrome.storage.onChanged.addListener(listener);
- chrome.tabs.query(
{
active: true,
currentWindow: true,
},
tabs => {
chrome.tabs.sendMessage(tabs[0].id, {
msg: Messages.DELETE_STUFF,
});
Would any of these cause the problem?
Why does closing the chrome extension popup prevent these from returning and make the service worker inactive? It seems like such a weird behavior. How do I make them persist and not lose the response.