Background Sync API — offline-first task registration via SyncManager.
Module backgroundSync | Source packages/front/fw/src/dom/sw/backgroundSync.js | Deps serviceWorker | Worker-safe no
Wrapper around the W3C Background Sync API (supported by Chrome/Chromium only at this date). Allows registering sync tags: the browser fires the sync event in the Service Worker once network connectivity is deemed sufficient. Designed for reliable offline replay (e.g. form submission, deferred upload).
The module operates page-side (main thread) via the ServiceWorkerRegistration. The sync event handler belongs to the Service Worker itself — see the complete example below.
Resolve
const backgroundSync = runtime.resolve('backgroundSync');
// Returns: { register, list, support }
API
| Method | Signature | Returns |
|---|---|---|
register |
(tag: string) => Promise<void> |
Registers a sync tag; throws BackgroundSyncNotSupported if unavailable |
list |
() => Promise<string[]> |
Currently registered sync tags |
support |
() => { available: boolean, sw: boolean } |
Synchronous support detection |
backgroundSync.register(tag)
Registers a tag with SyncManager. The SW will receive self.addEventListener('sync', event => event.tag === tag) when the browser estimates connectivity is restored.
- Throws
BackgroundSyncNotSupported(.name === 'BackgroundSyncNotSupported') ifSyncManageris absent from theServiceWorkerRegistration. - Idempotent: calling with the same tag twice has no effect.
backgroundSync.list()
Returns pending tags via SyncManager.getTags(). Useful for avoiding duplicate registrations.
backgroundSync.support()
Synchronous preliminary detection:
| Field | Meaning |
|---|---|
sw |
navigator.serviceWorker is present |
available |
sw && typeof SyncManager !== 'undefined' (heuristic — Chrome only) |
Does not guarantee that SyncManager is effectively accessible via the active registration; use register() with BackgroundSyncNotSupported error handling for definitive detection.
Examples
Register a tag with support check
const backgroundSync = runtime.resolve('backgroundSync');
const { available } = backgroundSync.support();
if (available) {
try {
await backgroundSync.register('sync-uploads');
console.log('Tag registered');
} catch (err) {
if (err.name === 'BackgroundSyncNotSupported') {
// Fallback: retry on online event
window.addEventListener('online', retryUploads, { once: true });
} else {
throw err;
}
}
} else {
window.addEventListener('online', retryUploads, { once: true });
}
Complete pattern with SW handler + online fallback
Page (main thread):
const backgroundSync = runtime.resolve('backgroundSync');
const serviceWorker = runtime.resolve('serviceWorker');
async function scheduleSyncOrFallback(tag, fallback) {
const { available } = backgroundSync.support();
if (available) {
try {
await backgroundSync.register(tag);
return; // the SW will take over
} catch (err) {
if (err.name !== 'BackgroundSyncNotSupported') throw err;
}
}
// Fallback: replay on next connection
window.addEventListener('online', fallback, { once: true });
}
await scheduleSyncOrFallback('sync-comments', () => fetch('/api/comments', { method: 'POST', body: pendingData }));
Service Worker (/sw.js):
self.addEventListener('sync', (event) => {
if (event.tag === 'sync-comments') {
event.waitUntil(replayPendingComments());
}
});
async function replayPendingComments() {
const pending = await getFromIndexedDB('pending-comments');
for (const item of pending) {
await fetch('/api/comments', { method: 'POST', body: JSON.stringify(item) });
await removeFromIndexedDB('pending-comments', item.id);
}
}
List pending tags
const backgroundSync = runtime.resolve('backgroundSync');
const pending = await backgroundSync.list();
console.log('Pending tags:', pending);
// ['sync-uploads', 'sync-comments']
Notes
- Limited browser support: Chrome/Chromium 49+ only as of the module date (May 2026). Firefox and Safari do not support the one-shot Background Sync API. Check caniuse.com/background-sync for current status.
- The recommended fallback on unsupported browsers is the
window.onlineevent + manual retry — simpler, but without delivery guarantee outside the session. SyncManageris only available if the page is served over HTTPS (orlocalhost). A SW registered over HTTP will never receive thesyncevent.- Periodic Background Sync (
PeriodicSyncManager) is a distinct API, out of scope for this module.
See also
- serviceWorker — Service Worker registration and lifecycle
- cache — HTTP response caching SW-side
- network — online/offline detection page-side