// Name of the cache const CACHE_NAME = 'my-site-cache-v1'; // List of assets to cache const ASSETS_TO_CACHE = [ '/', '/index.html', '/manifest.json', '/images/icon-192x192.png', '/images/icon-512x512.png', // Add any other assets you want to cache ]; // Install event self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => { return cache.addAll(ASSETS_TO_CACHE); }) ); }); // Activate event self.addEventListener('activate', (event) => { const cacheWhitelist = [CACHE_NAME]; event.waitUntil( caches.keys().then((cacheNames) => { return Promise.all( cacheNames.map((cacheName) => { if (!cacheWhitelist.includes(cacheName)) { return caches.delete(cacheName); } }) ); }) ); // Immediately claim any clients event.waitUntil(self.clients.claim()); }); // Fetch event self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then((cachedResponse) => { // Return cached response if found, otherwise fetch from network return cachedResponse || fetch(event.request).then((response) => { // Only cache valid responses if (!response || response.status !== 200 || response.type !== 'basic') { return response; } // Optionally cache the new response return caches.open(CACHE_NAME).then((cache) => { cache.put(event.request, response.clone()); return response; }); }); }) ); }); // Enhanced push event handler for WonderPush self.addEventListener('push', (event) => { if (!(self.Notification && self.Notification.permission === 'granted')) { return; } try { const data = event.data ? event.data.json() : {}; const title = data.title || 'Default Title'; const options = { body: data.body || 'Default body text', icon: '/images/icon-192x192.png', badge: '/images/icon-512x512.png', tag: data.tag || 'default-tag', data: data, // Store the full data object for click handling // Additional WonderPush specific options actions: data.actions || [], image: data.image, requireInteraction: data.requireInteraction || false, vibrate: data.vibrate || [200, 100, 200] }; event.waitUntil( self.registration.showNotification(title, options) ); } catch (err) { console.error('Error showing notification:', err); } }); // Notification click event handler self.addEventListener('notificationclick', (event) => { event.notification.close(); // Handle notification click const clickedNotification = event.notification; const action = event.action; const notificationData = clickedNotification.data || {}; let urlToOpen = notificationData.url || '/'; // Handle custom actions if present if (action && notificationData.actions) { const actionData = notificationData.actions.find(a => a.action === action); if (actionData && actionData.url) { urlToOpen = actionData.url; } } event.waitUntil( clients.matchAll({ type: 'window', includeUncontrolled: true }) .then((clientList) => { // If a window client is available, focus it for (const client of clientList) { if (client.url === urlToOpen && 'focus' in client) { return client.focus(); } } // If no window client is available, open a new window if (clients.openWindow) { return clients.openWindow(urlToOpen); } }) ); }); // Handle subscription change self.addEventListener('pushsubscriptionchange', (event) => { event.waitUntil( self.registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: self.registration.pushManager.getKey('p256dh') }) .then((subscription) => { // You might want to send the new subscription to your server console.log('Subscription renewed:', subscription); }) ); });