Shadcn Hooks

useNetwork

A hook to get the network state

Loading...

Installation

npx shadcn@latest add @hooks/use-network
pnpm dlx shadcn@latest add @hooks/use-network
yarn dlx shadcn@latest add @hooks/use-network
bun x shadcn@latest add @hooks/use-network

Copy and paste the following code into your project.

use-network.ts
import { useCallback, useRef, useSyncExternalStore } from 'react'

export interface NetworkState {
  since?: Date
  online?: boolean
  rtt?: number
  type?: string
  downlink?: number
  saveData?: boolean
  downlinkMax?: number
  effectiveType?: string
}

function getConnection() {
  const nav = navigator as any
  if (typeof nav !== 'object') {
    return null
  }
  return nav.connection || nav.mozConnection || nav.webkitConnection
}

function getConnectionProperty(): NetworkState {
  const c = getConnection()
  if (!c) {
    return {}
  }
  return {
    rtt: c.rtt,
    type: c.type,
    saveData: c.saveData,
    downlink: c.downlink,
    downlinkMax: c.downlinkMax,
    effectiveType: c.effectiveType,
  }
}

function serverSnapshot() {
  return {
    since: undefined,
    online: true,
    ...getConnectionProperty(),
  }
}

function getInitialOnlineState(): boolean {
  if (typeof navigator !== 'object') {
    return true
  }
  return navigator.onLine
}

export function useNetwork() {
  const networkState = useRef<NetworkState>({
    since: undefined,
    online: getInitialOnlineState(),
    ...getConnectionProperty(),
  })

  const subscribe = useCallback((onStoreChange: () => void) => {
    const onOnline = () => {
      networkState.current = {
        ...networkState.current,
        since: new Date(),
        online: true,
        ...getConnectionProperty(),
      }
      onStoreChange()
    }

    const onOffline = () => {
      networkState.current = {
        ...networkState.current,
        since: new Date(),
        online: false,
        ...getConnectionProperty(),
      }
      onStoreChange()
    }

    const onConnectionChange = () => {
      networkState.current = {
        ...networkState.current,
        since: new Date(),
        ...getConnectionProperty(),
      }
      onStoreChange()
    }

    window.addEventListener('online', onOnline)
    window.addEventListener('offline', onOffline)

    const connection = getConnection()
    connection?.addEventListener('change', onConnectionChange)

    return () => {
      window.removeEventListener('online', onOnline)
      window.removeEventListener('offline', onOffline)
      connection?.removeEventListener('change', onConnectionChange)
    }
  }, [])

  const snapshot = useCallback(() => networkState.current, [])

  return useSyncExternalStore(subscribe, snapshot, serverSnapshot)
}

API

/**
 * @see https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation
 * The network state
 */
export interface NetworkState {
  /**
   * The date when the network state was last updated
   */
  since?: Date
  /**
   * Whether the network is online
   */
  online?: boolean
  /**
   * The round-trip time in milliseconds
   */
  rtt?: number
  /**
   * The type of the network
   */
  type?: string
  /**
   * The downlink speed in Mbps
   */
  downlink?: number
  /**
   * Whether the user has enabled data saving
   */
  saveData?: boolean
  /**
   * The maximum downlink speed in Mbps
   */
  downlinkMax?: number
  /**
   * The effective type of the network
   */
  effectiveType?: string
}

/**
 * A hook to get the network state
 * @returns The network state
 */
export function useNetwork(): NetworkState

Credits

Last updated on