VUE

useNetworkStatus Composable

Reactive network status monitoring with offline/online detection and speed estimation

Vue3ComposablesNetworkOnlineStatusReactive

Code

import { ref, onMounted, onUnmounted } from 'vue';

interface NetworkStatus {
  isOnline: Ref<boolean>;
  downlink: Ref<number | null>;
  effectiveType: Ref<'slow-2g' | '2g' | '3g' | '4g' | null>;
  rtt: Ref<number | null>;
  saveData: Ref<boolean | null>;
}

export function useNetworkStatus(): NetworkStatus {
  const isOnline = ref(navigator.onLine);
  const downlink = ref<number | null>(null);
  const effectiveType = ref<'slow-2g' | '2g' | '3g' | '4g' | null>(null);
  const rtt = ref<number | null>(null);
  const saveData = ref<boolean | null>(null);

  const updateNetworkInfo = () => {
    __TOKEN_31__ (!navigator.connection) return;
    const conn = navigator.connection as NetworkInformation;
    downlink.value = conn.downlink;
    effectiveType.value = conn.effectiveType as any;
    rtt.value = conn.rtt;
    saveData.value = conn.saveData;
  };

  const handleOnline = () => {
    isOnline.value = true;
    updateNetworkInfo();
  };

  const handleOffline = () => {
    isOnline.value = false;
  };

  const handleConnectionChange = () => {
    updateNetworkInfo();
  };

  onMounted(() => {
    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);
    __TOKEN_37__ (navigator.connection) {
      navigator.connection.addEventListener('change', handleConnectionChange);
      updateNetworkInfo();
    }
  });

  onUnmounted(() => {
    window.removeEventListener('online', handleOnline);
    window.removeEventListener('offline', handleOffline);
    __TOKEN_38__ (navigator.connection) {
      navigator.connection.removeEventListener('change', handleConnectionChange);
    }
  });

  return { isOnline, downlink, effectiveType, rtt, saveData };
}

// Usage example
// const { isOnline, effectiveType } = useNetworkStatus();
// watch(isOnline, (online) => {
//   if (!online) showToast('You are offline!', { type: 'warning' });
// });