Created
March 16, 2018 10:27
-
-
Save selbekk/307a66aee447b80afee85b6b35bc815a to your computer and use it in GitHub Desktop.
A service worker with refresh dispatching
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { showSnackbar } from './actions'; | |
const isLocalhost = Boolean( | |
window.location.hostname === 'localhost' || | |
// [::1] is the IPv6 localhost address. | |
window.location.hostname === '[::1]' || | |
// 127.0.0.1/8 is considered localhost for IPv4. | |
window.location.hostname.match( | |
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ | |
) | |
); | |
export default function register(store) { | |
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { | |
// The URL constructor is available in all browsers that support SW. | |
const publicUrl = new URL(process.env.PUBLIC_URL, window.location); | |
if (publicUrl.origin !== window.location.origin) { | |
// Our service worker won't work if PUBLIC_URL is on a different origin | |
// from what our page is served on. This might happen if a CDN is used to | |
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 | |
return; | |
} | |
window.addEventListener('load', () => { | |
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; | |
if (isLocalhost) { | |
// This is running on localhost. Lets check if a service worker still exists or not. | |
checkValidServiceWorker(swUrl); | |
} else { | |
// Is not local host. Just register service worker | |
registerValidSW(swUrl, store); | |
} | |
}); | |
} | |
} | |
function registerValidSW(swUrl, store) { | |
navigator.serviceWorker | |
.register(swUrl) | |
.then(registration => { | |
registration.onupdatefound = () => { | |
const installingWorker = registration.installing; | |
installingWorker.onstatechange = () => { | |
if (installingWorker.state === 'installed') { | |
if (navigator.serviceWorker.controller) { | |
// At this point, the old content will have been purged and | |
// the fresh content will have been added to the cache. | |
// It's the perfect time to display a "New content is | |
// available; please refresh." message in your web app. | |
store.dispatch( | |
showSnackbar('A new version is available. Please refresh to get new features!') | |
); | |
} else { | |
// At this point, everything has been precached. | |
// It's the perfect time to display a | |
// "Content is cached for offline use." message. | |
console.log('Content is cached for offline use.'); | |
} | |
} | |
}; | |
}; | |
}) | |
.catch(error => { | |
console.error('Error during service worker registration:', error); | |
}); | |
} | |
function checkValidServiceWorker(swUrl) { | |
// Check if the service worker can be found. If it can't reload the page. | |
fetch(swUrl) | |
.then(response => { | |
// Ensure service worker exists, and that we really are getting a JS file. | |
if ( | |
response.status === 404 || | |
response.headers.get('content-type').indexOf('javascript') === -1 | |
) { | |
// No service worker found. Probably a different app. Reload the page. | |
navigator.serviceWorker.ready.then(registration => { | |
registration.unregister().then(() => { | |
window.location.reload(); | |
}); | |
}); | |
} else { | |
// Service worker found. Proceed as normal. | |
registerValidSW(swUrl); | |
} | |
}) | |
.catch(() => { | |
console.log( | |
'No internet connection found. App is running in offline mode.' | |
); | |
}); | |
} | |
export function unregister() { | |
if ('serviceWorker' in navigator) { | |
navigator.serviceWorker.ready.then(registration => { | |
registration.unregister(); | |
}); | |
} | |
} | |
© 2018 GitHub, Inc. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment