We are currently hosting a react app with amplify and have recently enabled the service worker via workbox to become PWA compatible. Our amplify app uses Cloudflare + S3 to serve our built react app. After enabling the service worker, when pushing new code and triggering a build, we noticed that if a user was on the site and refreshed their app, it would get a 404 error
https://ourwebsite.com/static/js/main.3j3k232.chunk.js 404 not found
This error would persist until the user would do a hard refresh on the browser. Our service worker previously was set to createHandlerBoundToURL() but we opted for NetworkFirst() instead because we were curious about solving the N+1 update problem. This was after the createHandlerBoundToURL() version of the service worker was deployed already.
import { clientsClaim } from 'workbox-core';
import { ExpirationPlugin } from 'workbox-expiration';
import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { NetworkFirst, NetworkOnly, StaleWhileRevalidate } from 'workbox-strategies';
declare const self: ServiceWorkerGlobalScope;
clientsClaim();
// Precache all of the assets generated by your build process.
// Their URLs are injected into the manifest variable below.
// This variable must be present somewhere in your service worker file,
// even if you decide not to use precaching. See https://cra.link/PWA
precacheAndRoute(self.__WB_MANIFEST);
// Set up App Shell-style routing, so that all navigation requests
// are fulfilled with your index.html shell. Learn more at
// https://developers.google.com/web/fundamentals/architecture/app-shell
const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
registerRoute(
// Return false to exempt requests from being fulfilled by index.html.
({ request, url }: { request: Request; url: URL }) => {
// If this isn't a navigation, skip.
if (request.mode !== 'navigate') {
return false;
}
// If this is a URL that starts with /_, skip.
if (url.pathname.startsWith('/_')) {
return false;
}
// If this looks like a URL for a resource, because it contains
// a file extension, skip.
if (url.pathname.match(fileExtensionRegexp)) {
return false;
}
// Return true to signal that we want to use the handler.
return true;
},
// createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html') // initially had this enabled
new NetworkFirst()
);
// An example runtime caching route for requests that aren't handled by the
// precache, in this case same-origin .png requests like those from in public/
registerRoute(
// Add in any other file extensions or routing criteria as needed.
({ url }) =>
url.origin === self.location.origin && url.pathname.endsWith('.png'),
// Customize this strategy as needed, e.g., by changing to CacheFirst.
new StaleWhileRevalidate({
cacheName: 'images',
plugins: [
// Ensure that once this runtime cache reaches a maximum size the
// least-recently used images are removed.
new ExpirationPlugin({ maxEntries: 50 }),
],
})
);
// This allows the web app to trigger skipWaiting via
// registration.waiting.postMessage({type: 'SKIP_WAITING'})
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
To reproduce this, we would only have to push new code and trigger a build, after it was completed the user would just need to refresh and they could be met with a 404 blank screen. We are using this PWA in a TWA android application.
Any help would be appreciated! We suspect it could also be an issue with CloudFront CDN as we have read that CDNs can cause issues with service workers and their caches.