Updating your code from Manifest V2 to V3 is a crucial step in ensuring your Chrome extension remains functional and secure. Manifest V3 introduces significant changes that impact how extensions are built and operated, including modifications to background scripts, permissions, and web request handling. This guide will walk you through the essential updates needed for your code to comply with the new standards set by Manifest V3, ensuring a smooth transition and optimal performance for your extension. Created by Exmo – a monetization platform for browser extensions.
Previos posts:
Note: Manifest V3 is generally supported in Chrome 88 or later. For information on support for extension features added in later Chrome versions, refer to the API reference documentation. If your extension requires a specific API, you can specify a minimum Chrome version in the manifest file.
This section outlines the necessary changes for code that is not part of the extension service worker. These changes are unrelated to other issues. The following two sections will cover replacing blocking web requests and enhancing security.
In Manifest V3, the executeScript()
method transitions from the tabs API to the scripting API. This transition entails adjustments to permissions in the manifest file as well as actual code modifications.
For the executeScript()
method, you’ll need:
scripting
” permission.activeTab
” permission.The scripting.executeScript()
method operates similarly to tabs.executeScript()
, with a few differences:
ScriptInjection.target
rather than as a method argument.The following example illustrates this:
Manifest V2
async function getCurrentTab() {/* ... */}
let tab = await getCurrentTab();
chrome.tabs.executeScript(
tab.id,
{
file: 'content-script.js'
}
);
In a background script file.
Manifest V3
async function getCurrentTab()
let tab = await getCurrentTab();
chrome.scripting.executeScript({
target: {tabId: tab.id},
files: ['content-script.js']
});
In the extension service worker.
In Manifest V3, the insertCSS()
and removeCSS()
methods transition from the tabs API to the scripting API. This transition requires adjustments to permissions in the manifest file as well as code modifications:
The functions in the scripting API operate similarly to their counterparts in the tabs API, with a few differences:
CSSInjection.target
instead of as a method argument.The following example illustrates how to use insertCSS()
. The process for removeCSS()
is identical.
Manifest V2
chrome.tabs.insertCSS(tabId, injectDetails, () => {
// callback code
});
In a background script file.
Manifest V3
const insertPromise = await chrome.scripting.insertCSS({
files: ["style.css"],
target: { tabId: tab.id }
});
// Remaining code.
In the extension service worker.
Browser actions and page actions, which were distinct concepts in Manifest V2, have become more similar over time. In Manifest V3, these concepts are merged into the Action API. This requires adjustments in both your manifest.json
file and your extension code compared to what you would have used in your Manifest V2 background script.
In Manifest V3, actions closely resemble browser actions, but the Action API does not provide hide()
and show()
methods like pageAction
did. If you still require page actions functionality, you can either emulate them using declarative content or use enable()
or disable()
methods with a tab ID.
To replace “browser_action
” and “page_action
” with “action” in the manifest.json:
Manifest V2
{
...
"page_action": { ... },
"browser_action": {
"default_popup": "popup.html"
}
...
}
Manifest V3
{
...
"action": {
"default_popup": "popup.html"
}
...
}
Where your Manifest V2 utilized the browserAction
and pageAction APIs, you should now transition to using the action API.
Manifest V2
chrome.browserAction.onClicked.addListener(tab => { ... });
chrome.pageAction.onClicked.addListener(tab => { ... });
Manifest V3
chrome.action.onClicked.addListener(tab => { ... });
In Manifest V3, many extension API methods now return promises. A Promise represents the eventual completion or failure of an asynchronous operation and allows you to handle the result when it’s ready. If you’re unfamiliar with Promises, you can learn more about them on MDN. This guide will explain how to use them in your Chrome extension.
For backward compatibility, some methods still support callbacks even after promise support is introduced. However, you cannot use both callbacks and promises in the same function call. If you provide a callback, the function won’t return a promise, and if you want a promise returned, you shouldn’t pass a callback. Certain API functionalities, such as event listeners, will still require callbacks. You can determine whether a method supports promises by checking for the “Promise”in its API reference.
To convert from a callback to a promise, simply remove the callback and handle the returned promise. The example below, taken from the optional permissions sample (newtab.js), demonstrates how to convert from a callback to a promise. Note that the promise version could be further simplified using async/await syntax.
Callback
chrome.permissions.request(newPerms, (granted) => {
if (granted) {
console.log('granted');
} else {
console.log('not granted');
}
});
Promise
const newPerms = { permissions: ['topSites'] };
chrome.permissions.request(newPerms)
.then((granted) => {
if (granted) {
console.log('granted');
} else {
console.log('not granted');
}
});
In Manifest V3, other extension contexts can only interact with extension service workers using message passing. Therefore, you’ll need to replace calls that expect a background context, such as:
Your extension scripts should use message passing to communicate between a service worker and other parts of your extension. This currently involves using sendMessage()
and implementing chrome.runtime.onMessage
in your extension service worker. In the long term, you should plan to replace these calls with postMessage()
and a service worker’s message event handler.
The methods and properties listed below need to be updated for Manifest V3.
Manifest V2 method or property | Replace with |
---|---|
Manifest V2 API | Manifest V3 API |
chrome.extension.connect() | chrome.runtime.connect() |
chrome.extension.connectNative() | chrome.runtime.connectNative() |
chrome.extension.getExtensionTabs() | chrome.extension.getViews() |
chrome.extension.getURL() | chrome.runtime.getURL() |
chrome.extension.lastError | Where methods return promises, use promise.catch() |
chrome.extension.onConnect | chrome.runtime.onConnect |
chrome.extension.onConnectExternal | chrome.runtime.onConnectExternal |
chrome.extension.onMessage | chrome.runtime.onMessage |
chrome.extension.onRequest | chrome.runtime.onMessage |
chrome.extension.onRequestExternal | chrome.runtime.onMessageExternal |
chrome.extension.sendMessage() | chrome.runtime.sendMessage() |
chrome.extension.sendNativeMessage() | chrome.runtime.sendNativeMessage() |
chrome.extension.sendRequest() | chrome.runtime.sendMessage() |
chrome.runtime.onSuspend (background scripts) | Not supported in extension service workers. Use the beforeunload document event instead. |
chrome.tabs.getAllInWindow() | chrome.tabs.query() |
chrome.tabs.getSelected() | chrome.tabs.query() |
chrome.tabs.onActiveChanged | chrome.tabs.onActivated |
chrome.tabs.onHighlightChanged | chrome.tabs.onHighlighted |
chrome.tabs.onSelectionChanged | chrome.tabs.onActivated |
chrome.tabs.sendRequest() | chrome.runtime.sendMessage() |
chrome.tabs.Tab.selected | chrome.tabs.Tab.highlighted |
Manifest V3 introduces several significant changes, including a transition to service workers for background tasks, new permissions structures, stricter security policies, and the use of promises instead of callbacks in many APIs. These changes enhance performance, security, and ease of use for developers.
In Manifest V3, the executeScript()
method moves to the scripting API. You need to add “scripting” permission in the manifest and update the code to use the scripting.executeScript()
method, which now accepts an array of files and requires passing a ScriptInjection object.
CSS injection methods insertCSS()
and removeCSS()
have moved to the scripting API in Manifest V3. You need to update your permissions and use the scripting.insertCSS()
and scripting.removeCSS()
methods, passing a CSSInjection object.
In Manifest V3, browser actions and page actions are merged into the Action API. Update your manifest to use “action” instead of “browser_action” or “page_action” and modify your code to use the chrome.action
API.
Many API methods in Manifest V3 return promises. You should remove callbacks and handle the returned promise using .then()
or async/await
syntax. This change simplifies asynchronous code and improves readability.
In Manifest V3, background tasks are handled by service workers, and you must use message passing for communication. Replace calls to chrome.runtime.getBackgroundPage()
and similar functions with sendMessage()
and implement message handlers in your service worker.
Host permissions are specified separately in Manifest V3. Move host permissions out of “permissions” and “optional_permissions” sections into “host_permissions” and “optional_host_permissions”
In Manifest V3, web accessible resources are defined more selectively to enhance security. Instead of listing files, provide an array of objects that map resources to specific URLs or extension IDs.
Yes, Google provides extensive documentation, guides, and sample extensions to help developers migrate from Manifest V2 to V3. The Chrome Extension Samples repo is a useful resource.
While Manifest V3 support is available in Chrome 88 and later, Google has provided timelines for the deprecation of Manifest V2. Check the official Chrome developer documentation for the latest updates on these timelines.
You’ve spent tons of time on your extension: optimized the code, squashed bugs, polished the…
In the browser extension development community, particularly among Firefox users, there is a bias against…
Affiliate marketing is a powerful tool for monetizing browser extensions. It requires no direct costs…
Your browser extension already delivers value to users, but have you considered making it a…
Creating a successful extension is a significant achievement, but one of the toughest challenges begins…
Developers looking for innovative ways to generate revenue can turn to Affiliate Marketing to Monetize…
This website uses cookies to enhance your browsing experience. By continuing to use our site, you consent to our use of cookies.
Terms and Conditions