docs / Runtime
Network State
Reactive browser network state: getNetworkState with online, effectiveType, downlink, rtt, saveData, plus watchNetwork subscriptions.
Vesk tracks browser connectivity through the Network Information API and `navigator.onLine`. It is designed for connectivity-aware boundaries and the router's offline fallback UI, and it degrades gracefully where the API is missing (Safari/Firefox): the extra fields become `null` / `'unknown'` and consumers fall back to the `online` flag alone.
getNetworkState
`getNetworkState()` returns a snapshot of the current connectivity as a plain `NetworkState` object. It is a read, not a subscription — combine it with `watchNetwork` to react to changes.
| Field | Type | Meaning |
|---|---|---|
| online | boolean | `navigator.onLine` — whether the browser believes it has connectivity. |
| effectiveType | 'slow-2g' | '2g' | '3g' | '4g' | 'unknown' | Estimated connection quality; `'unknown'` when the Network Information API is unavailable. |
| downlink | number | null | Estimated downlink in Mbps, or `null` when unsupported. |
| rtt | number | null | Estimated round-trip time in ms, or `null` when unsupported. |
| saveData | boolean | Whether the user's data-saver mode is active. |
// @client-only — the network APIs live in the client barrel
import { getNetworkState } from '@vesk/runtime';
const state = getNetworkState();
console.log(state.online); // true | false
console.log(state.effectiveType); // '4g' | '3g' | '2g' | 'slow-2g' | 'unknown'
console.log(state.downlink); // Mbps | null
console.log(state.rtt); // ms | null
console.log(state.saveData); // boolean
watchNetwork
`watchNetwork(cb)` subscribes to connectivity changes — online/offline flips plus `connection.change` events where the Network Information API is supported — and calls `cb(state)` with a fresh `NetworkState` on every change. It returns an unsubscribe function, and it is a no-op-safe no-op on the server (no `window` access is attempted). It is not auto-imported, so pull it from `@vesk/runtime`.
// @client-only — the network APIs live in the client barrel
import { watchNetwork } from '@vesk/runtime';
component NetworkStatus() {
let &[online] = track(navigator.onLine ?? true);
// watchNetwork calls you with a plain snapshot. Assigning to the tracked
// binding is the write — the compiler turns it into a cell set, so the
// template above follows it.
const unsubscribe = watchNetwork((state) => online = state.online);
on_destroy(unsubscribe);
<p class={online ? 'text-green-600' : 'text-red-600'}>
{online ? 'Online' : 'Offline'}
</p>
}
For a richer badge that reacts to the full state object, keep a tracked cell of the whole `NetworkState` and write it from the subscription:
// @client-only — the network APIs live in the client barrel
import { watchNetwork } from '@vesk/runtime';
component NetworkStatus() {
let &[online] = track(navigator.onLine ?? true);
// watchNetwork calls you with a plain snapshot. Assigning to the tracked
// binding is the write — the compiler turns it into a cell set, so the
// template above follows it.
const unsubscribe = watchNetwork((state) => online = state.online);
on_destroy(unsubscribe);
<p class={online ? 'text-green-600' : 'text-red-600'}>
{online ? 'Online' : 'Offline'}
</p>
}
On browsers without the Network Information API, `effectiveType` stays `'unknown'` and `downlink` / `rtt` are `null` — never assume those fields are present. Only `online` is universally available.