Skip to content

Instantly share code, notes, and snippets.

@cferdinandi
Last active December 17, 2024 11:58
Show Gist options
  • Save cferdinandi/6e4a73a69b0ee30c158c8dd37d314663 to your computer and use it in GitHub Desktop.
Save cferdinandi/6e4a73a69b0ee30c158c8dd37d314663 to your computer and use it in GitHub Desktop.
// Core assets
let coreAssets = [];
// On install, cache core assets
self.addEventListener('install', function (event) {
// Cache core assets
event.waitUntil(caches.open('app').then(function (cache) {
for (let asset of coreAssets) {
cache.add(new Request(asset));
}
return cache;
}));
});
// Listen for request events
self.addEventListener('fetch', function (event) {
// Get the request
let request = event.request;
// Bug fix
// https://stackoverflow.com/a/49719964
if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') return;
// HTML files
// Network-first
if (request.headers.get('Accept').includes('text/html')) {
event.respondWith(
fetch(request).then(function (response) {
// Create a copy of the response and save it to the cache
let copy = response.clone();
event.waitUntil(caches.open('app').then(function (cache) {
return cache.put(request, copy);
}));
// Return the response
return response;
}).catch(function (error) {
// If there's no item in cache, respond with a fallback
return caches.match(request).then(function (response) {
return response || caches.match('/offline.html');
});
})
);
}
// CSS & JavaScript
// Offline-first
if (request.headers.get('Accept').includes('text/css') || request.headers.get('Accept').includes('text/javascript')) {
event.respondWith(
caches.match(request).then(function (response) {
return response || fetch(request).then(function (response) {
// Return the response
return response;
});
})
);
return;
}
// Images
// Offline-first
if (request.headers.get('Accept').includes('image')) {
event.respondWith(
caches.match(request).then(function (response) {
return response || fetch(request).then(function (response) {
// Save a copy of it in cache
let copy = response.clone();
event.waitUntil(caches.open('app').then(function (cache) {
return cache.put(request, copy);
}));
// Return the response
return response;
});
})
);
}
});
@timeowilliams
Copy link

Thanks for sharing this!

However, I am getting errors in the console that coreID and imgID is not defined:

Screen Shot 2022-02-28 at 7 56 01 PM

@cferdinandi
Copy link
Author

@timeowilliams good catch! Just pushed a fix for a few naming issues that deviated from the article. Thanks!

@lucasdidthis
Copy link

Amazing work, thank you so much, amazing resource. I'm running into trouble with scripts that are an application (and not text) as well as font-files, though. Maybe you could update the boilerplate for those?

@mtonc
Copy link

mtonc commented Sep 14, 2022

Awesome resource. I never really understood service workers, but describing them as middleware and following this example made things click for me. Can't wait to test it out on some personal projects. Two small things, line 21 could be let { request } = event and on line 25, you can remove the event object, since you already have access to the request.

@pawan-poudel-github
Copy link

can use it without changing any content ?

@cferdinandi
Copy link
Author

@pawan-poudel-github Yes you can, though you might want to add some default assets to coreAssets array. But you can drop this right in as-is.

@Fesnel17
Copy link

Greate content, it really helped me in my PWA

@Offbeatmammal
Copy link

really helpful, but it seems to not be caching .js files for offline use? assume I've messed up somewhere - it seems to handle the .html, .css, .png, and .jpg files fine

@cferdinandi
Copy link
Author

@Offbeatmammal I don't think my 'text/javascript' MIME type check is correct. Browsers either changed how that's served, or I messed up when researching this (more likely the case). Looking right now to see if I can figure out what it should be.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment