Handling Events in Service Workers
Once a service worker is installed and registered, we need to handle key events like:
- Fetch Events: Serve cached resources when offline.
- Update Events: Ensure users get the latest version of the app.
- Cache Management: Remove old caches to free up storage.
1. Handling Fetch Events for Offline Access
When a user requests a resource, the service worker should check if it’s cached. If it is, the service worker serves the cached version instead of making a network request.
Modify service_worker.js
to intercept network requests:
self.addEventListener("fetch", (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
});
- If the requested resource is in the cache, it is served immediately.
- Otherwise, the request is sent to the network.
This approach allows pages and assets to load even when the user is offline.
2. Updating Service Workers and Caches
When an updated service worker is deployed, old caches should be removed to ensure users get the latest content.
Modify service_worker.js
:
const CACHE_NAME = "rails-pwa-cache-v2";
self.addEventListener("activate", (event) => {
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames.map((cache) => {
if (cache !== CACHE_NAME) {
console.log("Deleting old cache:", cache);
return caches.delete(cache);
}
})
);
})
);
});
- When a new service worker is activated, it loops through existing caches.
- If an old cache is found (
rails-pwa-cache-v1
), it is deleted. - This ensures only the latest assets are stored.
3. Handling Network Fallbacks for Dynamic Content
Some data, like API responses, might not be cached initially. A network-first approach can be used, where data is fetched from the network first, and if unavailable, a cached fallback is served.
Modify service_worker.js
:
self.addEventListener("fetch", (event) => {
event.respondWith(
fetch(event.request)
.then((response) => {
return caches.open(CACHE_NAME).then((cache) => {
cache.put(event.request, response.clone());
return response;
});
})
.catch(() => caches.match(event.request))
);
});
- The service worker tries to fetch data from the network first.
- If successful, it stores a copy in the cache for future use.
- If the network is unavailable, a cached response is returned.
This strategy works well for API-driven Rails applications that require real-time updates.
4. Handling Offline Fallback Pages
If a user visits an uncached page while offline, they should see an informative offline page.
1. Create an offline.html
file in public
:
<html>
<head><title>Offline</title></head>
<body>
<h1>You are offline</h1>
<p>Please check your internet connection and try again.</p>
</body>
</html>
2. Modify service_worker.js
to serve offline.html
:
self.addEventListener("fetch", (event) => {
event.respondWith(
fetch(event.request).catch(() => caches.match("/offline.html"))
);
});
Now, if a request fails due to no connectivity, the PWA serves an offline-friendly page instead of a generic browser error.