Code

Browser Web APIs

CDEFGHIJKLMNOPQRSTUVWXYZ

Background Fetch API

Experimental

Provides a method for managing large downloads that may take significant time. Unlike the Fetch API, downloads continue even if the user navigates away or closes the browser, with progress surfaced via a browser UI element.

MDN Reference

Key Interfaces
  • ServiceWorkerRegistration.backgroundFetch — Returns a BackgroundFetchManager for the registration.
  • BackgroundFetchManager.fetch(id, requests, options) — Starts a background fetch and returns a BackgroundFetchRegistration.
  • BackgroundFetchManager.get(id) — Returns an existing BackgroundFetchRegistration by ID.
  • BackgroundFetchRegistration — Tracks state, progress (downloaded / downloadTotal), and result of the fetch.
  • BackgroundFetchRecord — Represents an individual request/response pair within the fetch.
Example — Start a background fetch

Initiate a background fetch for a large file from the page. The browser shows download progress to the user even if the tab is closed.

const registration = await navigator.serviceWorker.ready;

const bgFetch = await registration.backgroundFetch.fetch(
  'my-download-id',
  ['/videos/episode-1.mp4'],
  {
    title: 'Episode 1',
    icons: [{ src: '/icon-512.png', sizes: '512x512', type: 'image/png' }],
    downloadTotal: 60 * 1024 * 1024, // 60 MB hint
  }
);

console.log('Fetch started:', bgFetch.id);
console.log('Result:', bgFetch.result); // "" | "success" | "failure"
Example — Handle completion in the service worker

Listen for backgroundfetchsuccess in the service worker to cache the downloaded responses.

// service-worker.js
self.addEventListener('backgroundfetchsuccess', (event) => {
  const bgFetch = event.registration;

  event.waitUntil(async function () {
    const cache = await caches.open('downloads');
    const records = await bgFetch.matchAll();

    const promises = records.map(async (record) => {
      const response = await record.responseReady;
      await cache.put(record.request, response);
    });

    await Promise.all(promises);
    event.updateUI({ title: 'Download complete!' });
  }());
});

self.addEventListener('backgroundfetchfail', (event) => {
  console.error('Background fetch failed:', event.registration.id);
});
Example — Track download progress

Poll or listen to the registration object to display progress in the UI.

const registration = await navigator.serviceWorker.ready;
const bgFetch = await registration.backgroundFetch.get('my-download-id');

if (bgFetch) {
  bgFetch.addEventListener('progress', () => {
    if (!bgFetch.downloadTotal) return;

    const percent = Math.round(
      (bgFetch.downloaded / bgFetch.downloadTotal) * 100
    );
    console.log(`Downloaded ${percent}%`);
  });
}