Last active
June 20, 2025 17:43
-
-
Save AmanuelCh/3247c027a2232219d0c761967b90b209 to your computer and use it in GitHub Desktop.
detects online/offline status using ping fallback, and online/offline events in addition to `window.navigator.onLine`. i wrote it for svelte component but you can just tweak some lines for your usecase. import isOnline, startNetworkWatcher or stopNetworkWatcher to your components as per your need
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { writable } from 'svelte/store'; | |
export const isOnline = writable<boolean>(navigator.onLine); | |
// for a lightweight check (<1KB actually) | |
const TEST_URL = 'https://clients3.google.com/generate_204'; | |
let interval: ReturnType<typeof setInterval> | null = null; | |
let isChecking = false; | |
// kinda useful to properly add/remove listeners | |
const onlineHandler = (): Promise<void> => checkConnection(); | |
const offlineHandler = (): void => isOnline.set(false); | |
async function checkConnection(): Promise<void> { | |
if (isChecking) return; | |
isChecking = true; | |
try { | |
const controller = new AbortController(); | |
const timeout = setTimeout(() => controller.abort(), 3000); | |
if (navigator.onLine) { | |
isOnline.set(true); | |
return; | |
} | |
const res = await fetch(TEST_URL, { | |
method: 'HEAD', | |
cache: 'no-cache', | |
mode: 'no-cors', | |
signal: controller.signal | |
}); | |
clearTimeout(timeout); | |
// if fetch didn't throw, assume online | |
if (res.ok) { | |
isOnline.set(true); | |
} | |
} catch { | |
isOnline.set(false); | |
} finally { | |
isChecking = false; | |
} | |
} | |
export function startNetworkWatcher(intervalMs = 30000): void { | |
if (interval !== null) return; | |
window.addEventListener('online', onlineHandler); | |
window.addEventListener('offline', offlineHandler); | |
checkConnection(); | |
interval = setInterval(checkConnection, intervalMs); | |
} | |
export function stopNetworkWatcher(): void { | |
if (interval === null) return; | |
clearInterval(interval); | |
interval = null; | |
window.removeEventListener('online', onlineHandler); | |
window.removeEventListener('offline', offlineHandler); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment