useNetworkState

Track network connection capability and status of the browser.

Network Status

Disconnected
0Mbps
Type
-
Latency
-
Save Data
Off
Health
Offline
Experimental Network Information API

Usage

import { useNetworkState } from 'usehooks-ts'
 
export default function App() {
  const network = useNetworkState()
 
  return (
    <div>
      <div>Online: {network.online ? 'Yes' : 'No'}</div>
      <div>Speed: {network.downlink} Mbps</div>
      <div>Type: {network.effectiveType}</div>
    </div>
  )
}

API

const networkState = useNetworkState()

Return Values

NameTypeDescription
onlinebooleantrue if browser is online
downlinknumberEffective bandwidth estimate in megabits per second
downlinkMaxnumberMaximum downlink speed estimate
effectiveTypestring('2g', '3g', '4g', 'slow-2g')
rttnumberEstimated effective round-trip time in milliseconds
saveDatabooleantrue if user has requested reduced data usage

Hook

import { useEffect, useState } from 'react'
 
interface NetworkInformation extends EventTarget {
  readonly type?: ConnectionType
  readonly effectiveType?: EffectiveConnectionType
  readonly downlinkMax?: number
  readonly downlink?: number
  readonly rtt?: number
  readonly saveData?: boolean
  onchange?: EventListener
}
 
type ConnectionType =
  | 'bluetooth'
  | 'cellular'
  | 'ethernet'
  | 'mixed'
  | 'none'
  | 'other'
  | 'unknown'
  | 'wifi'
  | 'wimax'
 
type EffectiveConnectionType = '2g' | '3g' | '4g' | 'slow-2g'
 
interface NetworkState {
  online: boolean
  downlink?: number
  downlinkMax?: number
  effectiveType?: EffectiveConnectionType
  rtt?: number
  saveData?: boolean
  type?: ConnectionType
}
 
const isNavigator = typeof navigator !== 'undefined'
 
const getConnection = (): NetworkInformation | undefined => {
  if (!isNavigator) return undefined
  return (
    (navigator as any).connection ||
    (navigator as any).mozConnection ||
    (navigator as any).webkitConnection
  )
}
 
const useNetworkState = (): NetworkState => {
  const [state, setState] = useState<NetworkState>({
    online: isNavigator ? navigator.onLine : true,
  })
 
  useEffect(() => {
    const handleOnline = () => {
      setState((prevState) => ({
        ...prevState,
        online: true,
      }))
    }
 
    const handleOffline = () => {
      setState((prevState) => ({
        ...prevState,
        online: false,
      }))
    }
 
    const handleConnectionChange = () => {
      const connection = getConnection()
 
      setState((prevState) => ({
        ...prevState,
        downlink: connection?.downlink,
        downlinkMax: connection?.downlinkMax,
        effectiveType: connection?.effectiveType,
        rtt: connection?.rtt,
        saveData: connection?.saveData,
        type: connection?.type,
      }))
    }
 
    window.addEventListener('online', handleOnline)
    window.addEventListener('offline', handleOffline)
 
    const connection = getConnection()
    if (connection) {
      connection.addEventListener('change', handleConnectionChange)
      handleConnectionChange() // Initial call to get current state
    }
 
    return () => {
      window.removeEventListener('online', handleOnline)
      window.removeEventListener('offline', handleOffline)
 
      if (connection) {
        connection.removeEventListener('change', handleConnectionChange)
      }
    }
  }, [])
 
  return state
}
 
export { useNetworkState }