Skip to content

useConnectivity ​

Whether the browser has a network, and a short "back online" state afterwards so the recovery is actually seen.

Open in demo

Import ​

ts
import { useConnectivity } from '@shared/composables/useConnectivity'

Signature ​

ts
function useConnectivity(): {
  online: Readonly<Ref<boolean>>
  status: ComputedRef<'idle' | 'offline' | 'reconnected'>
  RECONNECT_NOTICE_MS: number
}

Returns ​

MemberTypeDescription
onlineReadonly<Ref<boolean>>navigator.onLine, watched.
statusComputedRef<'idle' | 'offline' | 'reconnected'>The three states the banner draws.
RECONNECT_NOTICE_MSnumber2600. How long reconnected lasts.

The three states ​

statusWhen
'idle'Online, and nothing has gone wrong.
'offline'Disconnected.
'reconnected'Just came back, for 2.6 seconds.

Example ​

vue
<script setup lang="ts">
import { useConnectivity } from '@shared/composables/useConnectivity'

const { status } = useConnectivity()
</script>

<template>
  <div role="status" aria-live="polite">
    <p v-if="status === 'offline'">
      You appear to be offline. Changes will not be saved.
    </p>
    <p v-else-if="status === 'reconnected'">
      Back online.
    </p>
  </div>
</template>

Notes ​

  • navigator.onLine says whether the browser has a network, not whether that network reaches anything. A captive portal reads as online. That is why the wording is "you appear to be offline" rather than a flat statement.
  • The reconnect state is held for 2.6 seconds on purpose. A banner that disappears the instant the network returns leaves the reader unsure whether anything happened at all.
  • It is a module-scope singleton, so the banner and the /offline page cannot disagree, and the latch behind the reconnect message is shared between them.
  • Going offline again during the reconnect window clears the pending timer, so the states cannot cross.
  • online is readonly. To try the states out, use the browser's offline toggle or the preview above.