Read more

JavaScript: Testing whether the browser is online or offline

Henning Koch
May 25, 2022Software engineer at makandra GmbH

You can use the code below to check whether the browser can make connections to the current site:

await isOnline() // resolves to true or false

Limitations of navigator.onLine

Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

While you can use the built-in function navigator.onLine Show archive.org snapshot (sic), it is only a hint for whether the device can access the Internet.

When navigator.onLine === false you know for certain that the user device has no connection to the Internet. This means one of the following:

  • no WLAN network is connected and Ethernet cable is plugged in
  • the user has explicitly switched to offline mode (a feature offered by some browsers)
  • the user has enabled airplane mode on their phone
  • the user is emulating an offline connection using their browser's DevTools

However, when navigator.onLine === true we only know that the user has some form of network connection. We do not know whether the user can actually make connections. Some reasons why you may effectively be offline while navigator.onLine === true:

  • Your phone reports a network connection, but your mobile data plan is exhausted.
  • Your phone reports a network connection, but you just drove into a tunnel that blocks phone signals.
  • You have a network connection, but it's so slow that you're effectively offline ( "lie-fi" Show archive.org snapshot ).
  • You have a network connection, but limited to the local network.

The isOnline() function below checks if you can make real requests by re-fetching your site's favicon Show archive.org snapshot . If the favicon cannot be downloaded within 6 seconds, it considers your connection to be offline.

The code

async function isOnline({ path, timeout } = {}) {
  if (!navigator.onLine) return false

  path ||= document.querySelector('link[rel*=icon]')?.href || '/favicon.ico'
  timeout ||= 6000

  const controller = new AbortController()
  const timeoutTimer = setTimeout(() => controller.abort(), timeout);     

  try {
    await fetch(path, {
      cache: 'no-store',
      signal: controller.signal
    })
    return true
  } catch(error) {
    return false
  } finally {
    clearTimeout(timeoutTimer)
  }
}
Posted by Henning Koch to makandra dev (2022-05-25 09:34)