I'm trying to get my first service worker registered on a Heroku app. Front end has been built using create-react-app, backend uses Django on the same server. I've made a basic "hello world" service worker which works in development, but gives a 404 error in production. I think I might be misunderstanding the basic file system that I'm using in production.
My file system on my local directory essentially looks like this:
root
- public
- index.html
- sw.js
static
- manifest.json
- src
- app.js
- serviceWorker.js
...
serviceWorker.js checks the browser and then attempts to register the service worker:
...
navigator.serviceWorker
.register(`${process.env.PUBLIC_URL}/sw.js`)
.then(registration => {
...
//process.env.PUBLIC_URL returns http://localhost:3000/ in development, and https://www.mydomain.app/ in production
sw.js just contains dummy code:
self.addEventListener('install', function(event) {
console.log("Hello World")
})
When this is deployed to Heroku, yarn build
packages everything into a build directory, which looks like:
build
- index.html
- sw.js
- service-worker.js // added automatically by web-pack
- asset-manifest.json // added automatically by web-pack
- precache-manifest.xyz.js // added automatically by web-pack
- static
- css
- js
- manifest.json
In production, this fails to find the file sw.js during the register()
function. The same error is happening with the auto-generated service-worker.js, where it works in development but not in production (404):
"TypeError: Failed to register a ServiceWorker for scope ('https://www.mydomain.app/') with script ('https://www.mydomain.app/sw.js'): A bad HTTP response code (404) was received when fetching the script."
I think my use of PUBLIC_URL is correct, as it works in development and production to find manifest.json at<link rel="manifest" href="%PUBLIC_URL%/static/manifest.json" />
. I've checked the file system by using heroku run bash
and everything seems to be in the right place, what am I missing?