Skip to content

Instantly share code, notes, and snippets.

@AmanuelCh
Last active June 20, 2025 17:43
Show Gist options
  • Save AmanuelCh/3247c027a2232219d0c761967b90b209 to your computer and use it in GitHub Desktop.
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
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