Keptab Migrate to Manifest V3
Posed at 2023-06-22
Posted by mywaiting
Keptab has upgraded from Manifest V2 to Manifest V3, the newest version of the Chrome Extensions platform. To help you track your work, Chrome developer have provided a Chrome Offical Checklist summarizing the contents of these documents. You can access the content via the checklist and dive into the content.
Combining our own plugin upgrade process, let's talk about how to migrate to Manifest V3 in real action.

Keptab: manage tabs friendly and reduce tabs clutter
Update the manifest
The manifest.json
file requires a slightly different format for Manifest V3 than for Manifest V2. For most projects, just do it like this
// Manifest V2
"manifest_version": 2
// Manifest V3
"manifest_version": 3
Migrate to a service worker
In Manifest V3, background pages are replaced by a service worker. The manifest changes are listed below.
- Replace
background.scripts
withbackground.service_worker
in themanifest.json
. Note that theservice_worker
field takes a string, not an array of strings. - Remove
background.persistent
from themanifest.json
.
// Manifest V2
{
"background": {
"scripts": [
"backgroundContextMenus.js",
"backgroundOauth.js"
],
"persistent": false
},
}
// Manifest V3
{
"background": {
"service_worker": "service_worker.js",
"type": "module"
}
}
You will only need the type
field if you use ES modules (using the import
keyword). Its value will always be module
.
Update your code
Replace Browser Actions and Page Actions with Actions
Browser actions and page actions were separate concepts in Manifest V2. Though they started with distinct roles, the differences between them decreased over time. In Manifest V3, these concepts are consolidated into the Action API. This requires changes in your manifest.json
and extension code that is different from what you would have put in your Manifest V2 background script.
In the manifest.json
replace the browser_action
and page_action
fields with the action
field.
// Manifest V2
{
"page_action": { ... },
"browser_action": {
"default_popup": "popup.html"
}
}
// Manifest V3
{
"action": {
"default_popup": "popup.html"
}
}
Where your Manifest V2 used the chrome.browserAction
and chrome.pageAction
APIs, you should now use the chrome.action
API.
// Manifest V2
chrome.browserAction.onClicked.addListener(tab => { ... });
chrome.pageAction.onClicked.addListener(tab => { ... });
// Manifest V3
chrome.action.onClicked.addListener(tab => { ... });
Re-written code with service-worker
You'll need to make a few code adjustments to account for differences between the way background scripts and service workers function. To start with, the way a service worker is specified in the manifest file is different from how background scripts are specified. Additionally:
- Because they can't access the DOM or the
window
interface, you'll need to move such calls to a different API or into anchrome.offscreen
document. - Event listeners should not be registered in response to returned promises or inside event callbacks.
- Since they're not backward compatible with
XMLHttpRequest()
you'll need to replace calls to this interface with calls tofetch()
. - Since they terminate when not in use, you'll need to persist application states rather than rely on global variables. Terminating service workers can also end timers before they have completed. You'll need to replace them with
chrome.alarms
.
Register Context Menus
Because of service-worker
event lifecycle, the extension's chrome.runtime.onInstalled
event, which is fired when the extension (not the service worker) is first installed, when the extension is updated to a new version, and when Chrome is updated to a new version. Use this event to set a state or for one-time initialization, such as chrome.contextMenus
.
// service-worker.js
chrome.runtime.onInstalled.addListener((details) => {
if(details.reason !== "install" && details.reason !== "update") return;
chrome.contextMenus.create({
"id": "sampleContextMenu",
"title": "Sample Context Menu",
"contexts": ["selection"]
});
});
Browser startup and launch Extension
When a user profile starts, the chrome.runtime.onStartup
event fires but no service worker events are invoked. You can add a callback to invoked this API, make your extension launch after browser startup.
// service-worker.js
chrome.runtime.onStartup.addListener(() => {
// open your extension page here!
openYourExtensionPageCodeHere()
})
Callback for Extension Launch
Extension service workers respond to both the standard service worker events and to events in extension namespaces. They are presented together because often one type follows another during an extension's use.
Your callback for extension launch will be run in service-worker
IDLE work cycle.
// service-worker.js
const main() {
// do init or any other things
}
// directly run here!
main()
The End
Unlike the words in the Chrome official document, It is not an easy thing to migrate from Manifest V2 to Manifest V3. The most importan thing, I think, is that you must read the ffff**k documents with any words.
If you have any questions about this topic, feel free to leave a message.