Skip to content

Instantly share code, notes, and snippets.

@bvjebin
Last active October 4, 2020 21:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bvjebin/e391459d65442a5ab9609c84515e7b52 to your computer and use it in GitHub Desktop.
Save bvjebin/e391459d65442a5ab9609c84515e7b52 to your computer and use it in GitHub Desktop.
Medium article - service worker registration
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;
@prabu-ssb
Copy link

prabu-ssb commented Oct 4, 2020

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment