Skip to main content
Back to Guides
Setup5 min read

PWA Consent: Service Workers, Cache, and Push in Scope

The cookie rule was never only about cookies. A service worker's cache, its IndexedDB store, and a push subscription are all storage on the user's device, which means a PWA can trigger consent without setting a single cookie.

"No cookies, no banner" is wrong

Plenty of PWA teams assume that because they store data with the Cache API or IndexedDB instead of cookies, the cookie rule doesn't reach them. It does. Article 5(3) of the ePrivacy Directive governs storing or gaining access to information on a user's device, full stop. It never limited itself to cookies, and the EDPB's Guidelines 2/2023 (adopted 16 October 2024) spell out that the rule is technology-agnostic. localStorage, IndexedDB, and the Cache API are all in scope. A PWA runs on exactly those.

The rule still has an exemption for storage that's strictly necessary to deliver a service the user asked for. That's the line that matters for a PWA, because a service worker does both essential and non-essential things, often in the same file.

Where a service worker touches storage

A service worker is a script the browser keeps running in the background, separate from any page. It reaches storage in a few ways:

  • Cache Storage via the Cache API, holding response objects so the app works offline.
  • IndexedDB, for structured offline data and queued actions.
  • Background Sync, which defers a network request until connectivity returns.

Draw the line by purpose. Caching your app shell, CSS, and templates so the PWA opens offline is storage the user asked for when they installed the app; that's a strong essential-exemption case. Caching or replaying an analytics beacon, a marketing pixel, or an identifier is non-essential, and it needs consent before the worker does it. The mechanism doesn't decide the category. The purpose does, the same way it does for the tags in our guide to cookie categories.

The worker outlives the page

Here's what makes a PWA different from a normal single-page app. The service worker keeps running after the tab that registered it is gone. It intercepts network requests through its fetch event, and a request queued with Background Sync can fire later, after the browser is reopened. So the usual promise ("we only fire tags after consent") has to account for the worker, not the page alone. If the worker can beacon, it can beacon on its own schedule.

Two consequences. Don't register a tracking-capable worker, or don't let it beacon, until consent is granted. And when a visitor withdraws consent, tell the worker: clear the caches and IndexedDB stores that held non-essential data, and stop queuing anything new. A worker that keeps replaying analytics after opt-out is a live compliance problem precisely because it's invisible in the page.

Push notifications are a separate gate

PWAs can send push notifications, and this is where two consent concepts get confused. The browser's permission prompt for the Push API is a technical permission to show notifications. It is not GDPR or ePrivacy consent. If you use push for marketing or to profile behavior, you need a lawful basis for that, and in the EU that generally means consent collected properly, which a tapped browser dialog isn't.

Two practical rules. Don't fire the push permission prompt on first load bundled with the install nudge; ask when the user has a reason to say yes. And keep marketing push behind your consent record, so a user who never agreed to marketing isn't enrolled just because they allowed notifications for order updates.

Gate the whole worker, not the tags alone

The cleanest pattern registers only the essential offline worker up front and keeps any tracking-capable worker behind the consent signal:

if ('serviceWorker' in navigator) {
  // essential offline shell, safe to register on load
  navigator.serviceWorker.register('/sw-offline.js');
}

// tracking-capable worker waits for consent
cookiebeam.onConsent('analytics', () => {
  navigator.serviceWorker.register('/sw-analytics.js');
});

Splitting the worker into two files, or scoping one worker so its tracking paths check a consent flag before running, keeps the offline experience working while the measurement side stays dark until consent. Reading the consent state inside the worker matters, because the worker can't see your page's variables. Pass it in through postMessage or a stored flag the worker checks on each fetch, and update that flag when the visitor changes their mind.

iOS adds its own wrinkle

Web push on iOS only works once the user has added the PWA to their home screen, a limit Apple introduced with iOS 16.4, so the push question often doesn't even arise on a plain iOS Safari visit. When it does, the same rule holds: an allowed-notifications tap is not marketing consent. And because iOS WebViews and Safari apply Intelligent Tracking Prevention aggressively, a PWA that leans on client storage for measurement should expect that storage to be capped or cleared. That's one more reason to keep non-essential storage consent-gated and lightweight rather than treating a PWA's offline store as a durable analytics cache.

Getting it right

  1. Split the worker's jobs. Keep essential offline caching separate from any non-essential tracking, so you can gate one without disabling the other.
  2. Hold registration of tracking-capable behavior, or the beaconing itself, until consent lands.
  3. On withdrawal, clear the non-essential caches and IndexedDB entries and stop future queuing.
  4. Treat the push permission and marketing consent as two decisions, and don't let one stand in for the other.
  5. Test in a freshly installed PWA on a real device, and confirm nothing non-essential is cached or beaconed before consent.

CookieBeam exposes a consent signal the worker can read before it beacons, and its scanner sees the outbound connections a PWA opens so you can catch a worker firing early. For a hard stop that a client-side change can't undo, pair the signal with server-side enforcement. If your PWA is also a client-rendered app, the race-condition and route-change patterns in our single-page app consent guide apply on top of everything here.

PWA & Service Worker Cookie Consent Guide 2026 | CookieBeam | CookieBeam