Last active
October 4, 2020 21:17
-
-
Save bvjebin/e391459d65442a5ab9609c84515e7b52 to your computer and use it in GitHub Desktop.
Medium article - service worker registration
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 React from "react"; | |
import App, { Container } from "next/app"; | |
import { Provider } from "react-redux"; | |
import MainLayout from "../components/Layouts/MainLayout"; | |
class MyApp extends App { | |
static async getInitialProps({ Component, ctx }) { | |
return {} | |
} | |
state = { | |
showInstall: false | |
}; | |
componentDidMount() { | |
if ("serviceWorker" in navigator) { | |
window.addEventListener("load", () => { | |
navigator.serviceWorker.addEventListener("controllerchange", function() { | |
console.log("Controller loaded"); | |
window.location.reload(); | |
}); | |
navigator.serviceWorker.register("/service-worker.js", { scope: "/" }).then( | |
registration => { | |
console.log("Service worker registered", registration.scope); | |
if (!navigator.serviceWorker.controller) return; | |
registration.update(); | |
this.onNewServiceWorker(registration, () => { | |
this.showRefreshUI(registration); | |
}); | |
}, | |
function(err) { | |
console.log("ServiceWorker registration failed: ", err); | |
} | |
); | |
}); | |
} | |
} | |
showRefreshUI = registration => { | |
this.swRegistration = registration; | |
this.setState(st => { | |
st.showInstall = true; | |
return st; | |
}); | |
}; | |
installUpdate = () => { | |
if (!this.swRegistration.waiting) return; | |
this.swRegistration.waiting.postMessage("skipWaiting"); | |
this.setState(st => { | |
st.showInstall = false; | |
return st; | |
}); | |
}; | |
onNewServiceWorker = (registration, callback) => { | |
if (registration.waiting) { | |
// SW is waiting to activate. Can occur if multiple clients open and | |
// one of the clients is refreshed. | |
return callback(); | |
} | |
function listenInstalledStateChange() { | |
registration.installing.addEventListener("statechange", function(event) { | |
if (event.target.state === "installed") { | |
// A new service worker is available, inform the user | |
callback(); | |
} | |
}); | |
} | |
if (registration.installing) { | |
return listenInstalledStateChange(); | |
} | |
// We are currently controlled so a new SW may be found... | |
// Add a listener in case a new SW is found, | |
registration.addEventListener("updatefound", listenInstalledStateChange); | |
}; | |
render() { | |
const { Component, pageProps } = this.props; | |
return ( | |
<Container> | |
<Provider store={reduxStore}> | |
<MainLayout {...pageProps}> | |
<Component {...pageProps} /> | |
</MainLayout> | |
<div id="modal-root" /> | |
{this.state.showInstall && ( | |
<div className="sw-install text-right"> | |
<button type="button" className="btn btn-primary" onClick={this.installUpdate}> | |
Install Update | |
</button> | |
</div> | |
)} | |
</Provider> | |
</Container> | |
); | |
} | |
} | |
export default MyApp; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hei! I came across your medium article on offline-first and indexeddb. I am working on a similar scenario and was wondering if you could share your code (mainly the indexeddb, image handling parts and postMessage logic) ? Thanks in advance!