-
Notifications
You must be signed in to change notification settings - Fork 32
Manifest V3
Save in 4.0.0 is a Manifest V3 extension on both Firefox and Chrome, from a single manifest.json.
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.jsonnow 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.
-
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.
- One MV3 manifest serves both browsers; each ignores the other's
backgroundkey. - 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.
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 |
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.)
- 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 adata:URL. If the offscreen document can't be created, it falls back to thedata:URL path. Firefox event pages havecreateObjectURLdirectly, so no offscreen document is needed.