Append reload notice on create-react-app & registerServiceWorker.js
Tags: react, javascript, serviceworker, createreactapp
Published: 2018-03-19 13:09:25

---
title: Append reload notice on create-react-app & registerServiceWorker.js
published: true
description: Example for create-react-app's registerServiceWorker reload notice.
tags: React, javascript, service-worker, create-react-app
---


`create-react-app` has `registerServiceWorker.js` by default.

I knew that this feature enable offline caching, but I felt it was hard to understand how to handle it (and sometime disalbed it).

I try to make show reload modal example like this.

--- 
![screenshot](https://thepracticaldev.s3.amazonaws.com/i/c5b0dk8qu4a5aj4fnuq3.gif)

[Source Code](https://github.com/inuscript/example-service-worker.git)

---

## 1. Prepare

By Default create-react-app, is not easy for local service-worker debugging.

I `eject` create-react-app and install [`serve`](https://github.com/zeit/serve). ( and need disable `serve` cache-control. )

```js
{
  "scripts": {
    "start":
      "NODE_ENV=production webpack --config config/webpack.config.prod.js --watch",
    "static": "serve -c 0 -s build -o --local"
  }
}
```

And start like this.

```
$ yarn start & yarn static
```

## 2. Append event dispatching when `onupdatefound`


When ServiceWorker detects an update, [`onupdatefound`](https://github.com/facebook/create-react-app/blob/0b1d6365768ae3bd267b042b74bab249673f1a9f/packages/react-scripts/template/src/registerServiceWorker.js#L63-L69) of `registerServiceWorker` is executed, and I append distpatch event here.


```js
registration.onupdatefound = () => {
  const installingWorker = registration.installing;
    installingWorker.onstatechange = () => {
        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.
          console.log("New content is available; please refresh.");
        
          // Append dispatch event
          const event = new Event("newContentAvailable");
          window.dispatchEvent(event);
        } else {
           :
```

[In next version](https://github.com/facebook/create-react-app/blob/cb3f835586d2f1e3b9ddcf3a29442c9d76eaef84/packages/react-scripts/template/src/serviceWorker.js#L71-L73), service worker script got `config.onUpdate` callback.
We do not need to add the code directly to `registerServiceWorker.js`


## 2. Create `<ReloadModal>`

Next, I append `<ReloadModal>` that catch global custom `newContentAvailable` event.

```jsx

// Main App
class App extends Component {
  render() {
    return (
      <div className="App">
        <ReloadModal />
            :
      </div>
    );
  }
}

class ReloadModal extends Component {
  state = {
    show: false
  };
  componentDidMount() {
    // Handle global event.
    window.addEventListener("newContentAvailable", () => {
      this.setState({
        show: true
      });
    });
  }
  onClick = () => {
    // Reload when modal click.
    window.location.reload(window.location.href);
  };
  render() {
    if (!this.state.show) {
      return null;
    }
    // <Modal> is common fixed component.
    return (
      <Modal onClick={this.onClick}>
        <span> New Content Available!please reload </span>
      </Modal>
    );
  }
}
```

## Conclusion

After this, I can got result like screenshot.

But I'm not confident in this implementation.
Please tell me if more better way.