Progressive Web App: How to detect and handle when connection is up again

Hank Phung picture Hank Phung · Jun 26, 2017 · Viewed 16.6k times · Source

With a PWA, we can handle when the device connection is down with offline mode. But how do we detect a fixed network connection and automatically reload/re-activate the application?

Answer

tony19 picture tony19 · Jun 26, 2017

You could monitor the offline and online events, which are widely supported. Further, you could test connectivity by attempting to fetch HEAD from the target server URL:

// Test this by running the code snippet below and then
// use the "Offline" checkbox in DevTools Network panel

window.addEventListener('online', handleConnection);
window.addEventListener('offline', handleConnection);

function handleConnection() {
  if (navigator.onLine) {
    isReachable(getServerUrl()).then(function(online) {
      if (online) {
        // handle online status
        console.log('online');
      } else {
        console.log('no connectivity');
      }
    });
  } else {
    // handle offline status
    console.log('offline');
  }
}

function isReachable(url) {
  /**
   * Note: fetch() still "succeeds" for 404s on subdirectories,
   * which is ok when only testing for domain reachability.
   *
   * Example:
   *   https://google.com/noexist does not throw
   *   https://noexist.com/noexist does throw
   */
  return fetch(url, { method: 'HEAD', mode: 'no-cors' })
    .then(function(resp) {
      return resp && (resp.ok || resp.type === 'opaque');
    })
    .catch(function(err) {
      console.warn('[conn test failure]:', err);
    });
}

function getServerUrl() {
  return document.getElementById('serverUrl').value || window.location.origin;
}
<fieldset>
  <label>
    <span>Server URL for connectivity test:</span>
    <input id="serverUrl" style="width: 100%">
  </label>
</fieldset>
<script>document.getElementById('serverUrl').value = window.location.origin;</script>

<p>
  <i>Use Network Panel in DevTools to toggle Offline status</i>
</p>

One technique of handling this:

  • Offline event

    • show offline icon/status
    • enable only features that are available offline (via cached data)
  • Online event

    • show online icon/status
    • enable all features