The Cache API provides a storage mechanism for Request and Response objects. It's the foundation for all offline strategies.
// Open or create a cache
caches.open('my-cache-v1').then(cache => {
// Add a single request/response
cache.add('/api/data.json');
// Add multiple URLs
cache.addAll(['/css/styles.css', '/js/app.js']);
// Manually put a response
cache.put('/api/data.json', new Response('{"status":"ok"}'));
// Match a request
cache.match('/api/data.json').then(response => {
if (response) { /* use cached response */ }
});
// Delete from cache
cache.delete('/old-asset.js');
});
// List all caches
caches.keys().then(names => console.log(names));
// Delete an entire cache
caches.delete('old-cache-v1');
Return cached content if available; otherwise fetch from network. Best for static assets.
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request)
.then(cached => cached || fetch(event.request))
);
});
Try the network first; fall back to cache if offline. Best for frequently updated content.
self.addEventListener('fetch', (event) => {
event.respondWith(
fetch(event.request)
.then(response => {
return caches.open('dynamic').then(cache => {
cache.put(event.request, response.clone());
return response;
});
})
.catch(() => caches.match(event.request))
);
});
Return cached content immediately, then update the cache with the network response. Best for content that doesn't need instant freshness.
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then(cached => {
const fetchPromise = fetch(event.request).then(response => {
return caches.open('dynamic').then(cache => {
cache.put(event.request, response.clone());
return response;
});
});
return cached || fetchPromise;
})
);
});
// Network only - always fetch from network
event.respondWith(fetch(event.request));
// Cache only - always serve from cache (fail if not cached)
event.respondWith(caches.match(event.request));
// Pattern: Cache with network update
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('/api/')) {
event.respondWith(
caches.open('api-cache').then(cache => {
return cache.match(event.request).then(cached => {
const networkPromise = fetch(event.request).then(response => {
cache.put(event.request, response.clone());
return response;
});
return cached || networkPromise;
});
})
);
}
});