Skip to content

Manifest V3

Ng Guoyou edited this page Jul 10, 2026 · 14 revisions

Save in 4.0.0 is a Manifest V3 extension on both Firefox and Chrome, from a single manifest.json.

Why Manifest V3

Dear developer,

We’re concluding the transition to Chrome Manifest V3 with the removal of all remaining Manifest V2 extensions from the Chrome Web Store on August 31, 2026.

(…)

– The Chrome Web Store Team

  • Chrome removed Manifest V2. Chrome disabled MV2 extensions, so an MV3 build is required to stay on the Chrome Web Store. This was the forcing reason.
  • One manifest for both browsers. Firefox supports MV3 too, so a single MV3 manifest.json now serves Firefox and Chrome instead of a per-browser setup — less divergence to maintain.
  • AI got good enough to maintain unmaintainable legacy software — I wouldn't have had the time to untangle this mess otherwise.

Requirements

  • Firefox 121+ — runs the background as an event page (background.scripts).
  • Chrome / Edge 121+ — runs the background as a service worker (background.service_worker).

Older browsers are not supported. If downloads stop working after an update, check your browser version first.

What changed

  • One MV3 manifest serves both browsers; each ignores the other's background key.
  • The background is non-persistent on both — it sleeps when idle and wakes on events. In-flight downloads, the pending counter, and the recovery filename are persisted to session storage so a mid-download restart still fires notifications and keeps the routed name.
  • Feature detection, not browser sniffing, picks each mechanism:
Feature Firefox (event page) Chrome (service worker)
Referer header blocking webRequest declarativeNetRequest session rule
Blob downloads URL.createObjectURL (event pages have a DOM) createObjectURL in an offscreen document; base64 data: URL if unavailable

See Firefox vs Chrome for the full per-browser breakdown.

Deprecations and removals

WebExtension features removed or changed in Manifest V3, and how Save in adapts:

Removed / changed Replacement In Save in
Persistent background page Non-persistent service worker (Chrome) / event page (Firefox) Download-tracking state persisted to session storage
Blocking webRequest (Chrome only) declarativeNetRequest Referer header uses declarativeNetRequestWithHostAccess on Chrome, blocking webRequest on Firefox
runtime.getBackgroundPage() Messaging (runtime.sendMessage) The options page talks to the background over messages
window / document / URL.createObjectURL in the background (Chrome) offscreen document; data-URL fallback Large fetched files get a blob URL from an offscreen document; base64 data: URL if it is unavailable
Cross-origin fetch from content scripts Background fetch (host permission) Fetch via content script deprecated → use Fetch via Fetch API
Remotely hosted code Bundled only N/A — all sources are first-party and unminified

Firefox host permissions and upgrades

Manifest V3 changes how Firefox treats host permissions — the sites an extension may access (Save in requests <all_urls>, needed for the Referer feature and click-to-save). Under MV2 a required host permission was granted at install and could not be revoked without uninstalling. Under MV3 host permissions are opt-in and revocable at any time from about:addons. Early Firefox MV3 (before Firefox 127) did not even show them in the install prompt, so a freshly installed extension could sit silently unable to access pages. Since Firefox 127 (June 2024) host permissions are shown in the install prompt and granted when the user accepts.

Upgrading from the last MV2 release (3.7.3) does not lose host access. When Firefox updates an extension it preserves the existing permission state and migrates a previously-granted MV2 required host permission into MV3's granted-origins store. The update applies with no prompt and the extension stays enabled — nothing to re-grant.

This was verified directly against Firefox's own permission store: installing 3.7.3 (MV2) and then updating to the MV3 build (same add-on ID) leaves <all_urls> granted, with the add-on active and no permission prompt shown. A control confirmed the update path preserves rather than re-grants — revoking <all_urls> and then updating to a higher version keeps it revoked — so the carried-over grant is a genuine migration of the prior MV2 permission, not an install-time default. (A brand-new install on a pre-127 Firefox is the only case that starts out un-granted; it does not affect anyone upgrading from a current version.)

User-visible notes

  • Nothing to reconfigure — settings and menus carry over.
  • The Referer feature uses different engine internals per browser but the same option and site whitelist.
  • Downloads via the Fetch API fallback go through an offscreen document on Chrome — it has a DOM and createObjectURL, so large fetched files become a blob URL instead of being base64-buffered into a data: URL. If the offscreen document can't be created, it falls back to the data: URL path. Firefox event pages have createObjectURL directly, so no offscreen document is needed.

Clone this wiki locally