Technical
Service Workers in TWAs: Offline Modes and Web Push
August 14, 2026 · 7 min read
Converting a Progressive Web App into an Android application via a Trusted Web Activity relies on a core technology: the service worker. Because a TWA is not a simple WebView wrapper, but rather a specialized browser instance powered by the system default web engine, it inherits the full capability of modern web APIs. Understanding how service workers behave within a packaged Android application is the key to delivering native-grade offline experiences and reliable background push notifications.
How Service Workers Function Inside a Trusted Web Activity
A Trusted Web Activity runs inside a customized browser tab, meaning it shares the same cookie jar, storage space, and service worker registration as the standard browser on the user device. If a user visits your website in Chrome and subsequently installs your TWA from the Google Play Store, the application shares the same cached assets and session state.
When the user launches your app from their Android home screen, the TWA starts the service worker immediately, checking for network connectivity and serving cached assets based on your defined caching strategy. This shared architecture ensures that resource utilization is minimised, while updates deployed to your web server are immediately picked up by the application on the user device without requiring a manual update through the Google Play Store.
Fulfilling Google Play Quality Guidelines with Offline Fallbacks
Google Play maintains strict quality guidelines for applications listed in its store. A primary requirement is that applications must not crash or display a blank screen when the user has no active internet connection. If a standard web page fails to load, the browser displays its default offline error page. Within a native application context, showing a browser error page degrades the user experience and can lead to app rejection or removal from the store.
To prevent this, your service worker must implement a robust offline fallback strategy. This is achieved by caching a dedicated offline HTML page during the service worker installation phase. If a network request fails and there is no cached version of the requested page, the service worker intercepts the failed request and serves the pre-cached offline page instead.A typical offline fallback implementation within your service worker script matches the following pattern:
self.addEventListener('install', event => { event.waitUntil(caches.open('offline-cache').then(cache => cache.add('/offline.html'))); }); self.addEventListener('fetch', event => { if (event.request.mode === 'navigate') { event.respondWith(fetch(event.request).catch(() => caches.match('/offline.html'))); } });
This implementation guarantees that your application will always render a branded, functional offline user interface, satisfying Google Play quality guidelines and providing a smooth user experience even during network drops.
Web Push Notifications in TWAs
One of the greatest advantages of using a Trusted Web Activity over a traditional WebView wrapper is native support for Web Push notifications. WebView components do not natively support the Web Push API, forcing developers to integrate complex native SDKs. Because TWAs leverage the system browser engine, they fully support standard W3C Web Push APIs and the Notification API.
When your application requests permission to display notifications, the browser engine handles the system-level permission request. On modern Android versions, this triggers the standard native permission dialog. Once the user grants permission, your service worker can receive push messages in the background, even when the TWA application is closed.
| Capability | Standard WebView Wrapper | Trusted Web Activity (TWA) | Native Java/Kotlin App |
|---|---|---|---|
| Shared Cookies & Cache | No | Yes (with system browser) | No |
| W3C Web Push Support | No | Yes | No (requires native SDKs) |
| Offline Caching via Service Worker | No (requires custom Java cache) | Yes | No (requires custom local database) |
| Google Play Compliance | Requires manual wrapper maintenance | Built-in engine compliance | Full compliance |
To implement push notifications inside your TWA, you register a push subscription using your VAPID public key. When your server sends a push payload via a push service, the Android system wakes up your service worker to handle the push event, allowing you to display a rich notification complete with action buttons, custom badges, and high-resolution icons.
Managing Service Worker Updates and Lifecycle Control
Because your TWA application relies on your web server to deliver files, managing the lifecycle of your service worker is crucial. When you update your web application, the browser checks for an updated service worker script in the background. If a byte-by-byte difference is detected, the new service worker is downloaded and installed.
By default, an updated service worker enters a waiting state, deferring activation until all open tabs running the application are closed. For a TWA user, this can cause confusion, as closing the app via the Android task manager does not always destroy the underlying browser process instantly. To resolve this, you must implement update prompts or use programmatic control to force the service worker to skip the waiting phase.
Using the self.skipWaiting method in your service worker, combined with clients.claim in the activation event, ensures that updates are applied immediately. This prevents a mismatch where a user runs an older cached version of your app interface that attempts to communicate with updated backend APIs, maintaining application stability across all active installations.
Ready to ship your Android app?
Paste your PWA URL, get a signed APK and a Google Play ready AAB in minutes.
Build my app