I recently wanted to know if it was possible to create a custom 404 page for a website if you didn't have access to the backend server. I thought it might be difficult since without a server you wouldn't be able to catch the request for pages and return the 404 page based on a failed request.
After my research didn't turn up anything, I had an idea that I thought might work.
I remembered that Service Workers could intercept network requests and respond with cached resources. Typically this is used to serve a custom offline page when the user navigates to a page that hasn't been cached yet. But what if we could use that same principle to serve a custom 404 page when the request fails?
There wasn't a lot of information available on doing something that like, but I did find a Google lab article on Service Workers which had an small section on serving a custom 404 from the cache. They didn't list the solution in the article, so I had to open their github repo to find it.
Turns out that it is indeed possible to serve a custom 404 page from a service worker. All it takes is first caching the 404 page and then looking at the response.status
of a fetch
request. If it's 404, return the cached 404 page.
Now whenever the user enters a URL that isn't found, the Service Worker will intercept the request and return your custom 404. No server required.
const filesToCache = [
'/',
'404.html'
];
const staticCacheName = 'pages-cache-v1';
self.addEventListener('install', event => {
event.waitUntil(
caches.open(staticCacheName).then(cache => {
return cache.addAll(filesToCache);
});
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
// found a cached resource
if (response) {
return response;
}
// request the non-cached resource
return fetch(event.request).then(response => {
// fetch request returned 404, serve custom 404 page
if (response.status === 404) {
return caches.match('404.html');
}
});
});
);
});