useConnectivity
Whether the browser has a network, and a short "back online" state afterwards so the recovery is actually seen.
vue
<script setup lang="ts">
import OfflineBanner from '@shared/components/common/OfflineBanner.vue'
import { useConnectivity } from '@shared/composables/useConnectivity'
import { Badge } from '@shared/components/ui/badge'
const { online, status, RECONNECT_NOTICE_MS } = useConnectivity()
</script>
<template>
<div class="flex flex-col gap-3">
<OfflineBanner />
<div class="flex flex-wrap items-center gap-2">
<Badge :variant="online ? 'outline' : 'destructive'">
browser: {{ online ? 'online' : 'offline' }}
</Badge>
<Badge variant="outline">
status: {{ status }}
</Badge>
</div>
<p class="sa-text-sm text-muted-foreground">
Switch your network off and the banner appears at the top of the window.
Switch it back on and the confirmation holds for {{ RECONNECT_NOTICE_MS }}ms.
</p>
</div>
</template>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
| Member | Type | Description |
|---|---|---|
online | Readonly<Ref<boolean>> | navigator.onLine, watched. |
status | ComputedRef<'idle' | 'offline' | 'reconnected'> | The three states the banner draws. |
RECONNECT_NOTICE_MS | number | 2600. How long reconnected lasts. |
The three states
status | When |
|---|---|
'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.onLinesays 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
/offlinepage 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.
onlineis readonly. To try the states out, use the browser's offline toggle or the preview above.
Related
- Offline banner — the component.
- Error page layout — the
/offlinepage.