Note
navigator.onLine lies. It tells you the browser thinks it has a network connection, not whether your app can reach the internet. This library uses is-online — which actually pings real endpoints — so you can trust the answer.
- Context provider — polls once, broadcasts via React Context to every consumer in the tree
useIsOnlinehook — call it standalone or read the shared context value withuseContext(IsOnlineContext)- Built on
is-onlinefor accuracy - Listens to HTML5
online/offlineevents for instant updates - Works in Electron, Next.js (client + server), and the browser
- Exposes
{ isOnline, isLoading, error } - Written in TypeScript with type definitions
npm install react-is-online-contextimport { IsOnlineContextProvider } from "react-is-online-context";
const App = () => {
// See `is-online` for available options.
const options = { timeout: 5000 };
return (
<IsOnlineContextProvider {...options}>
<YourApp />
</IsOnlineContextProvider>
);
};import { useContext } from "react";
import { IsOnlineContext } from "react-is-online-context";
const StatusBar = () => {
const { isOnline, isLoading, error } = useContext(IsOnlineContext);
if (isLoading) return null;
if (error) return <span>Could not check</span>;
return <span>{isOnline ? "Online" : "Offline"}</span>;
};import { useIsOnline } from "react-is-online-context";
const StatusBar = () => {
const { isOnline } = useIsOnline();
return <span>{isOnline ? "Online" : "Offline"}</span>;
};Tip
Live, interactive demo on Chromatic / Storybook.
Wraps your tree and supplies IsOnlineContext. Accepts the following is-online options:
| Prop | Type | Description |
|---|---|---|
timeout |
number |
Milliseconds to wait for each check before giving up |
ipVersion |
4 | 6 |
Force a specific IP version |
Need other is-online options forwarded? Open an issue.
A React context whose value is:
| Field | Type | Description |
|---|---|---|
isOnline |
boolean |
Whether the app can reach the internet |
isLoading |
boolean |
First check still in progress |
error |
Error | null |
Set if the last check threw |
Returns the same { isOnline, isLoading, error } shape. Works standalone — it doesn't require the provider — but each call starts its own polling loop. If you have more than one consumer, wrap them in <IsOnlineContextProvider /> and read the shared value via useContext(IsOnlineContext) to avoid duplicate network traffic.
Why use the context vs. calling the hook directly?
The hook is self-contained — it polls and tracks online state on its own. That's fine for a single consumer. But if multiple components each call useIsOnline(), you get independent polling loops (three components → three sets of network checks). Wrapping the tree in <IsOnlineContextProvider /> polls once and broadcasts the value to every consumer via context. Same data, less network noise.
Why not just navigator.onLine?
navigator.onLine only reports whether the browser has some network interface attached. A laptop on a Wi-Fi network with no internet upstream will still report true. VMs lie about it. Captive portals lie about it. is-online pings real endpoints and gives you a real answer.
Does it work in SSR / Next.js?
Yes. The provider gracefully no-ops on the server (no window), and the first client render kicks off the actual check.
| react-is-online-context | react-detect-offline |
use-network-state |
navigator.onLine |
|
|---|---|---|---|---|
| Real internet check (not just NIC) | ✅ (is-online) | ✅ (polls a URL) | ❌ (uses navigator.onLine) |
❌ |
| Lies about captive portals | ❌ | ❌ | ✅ | ✅ |
| Shared context (poll once, broadcast to N consumers) | ✅ | ❌ (per-component) | ❌ | n/a |
| Hook and Context | ✅ | render-prop only | hook only | n/a |
| TypeScript types | ✅ | partial | ✅ | ✅ |
| SSR-safe | ✅ | ✅ | ✅ | needs guards |
| Bundle size (min+gz) | ~3 KB + is-online |
~2 KB | ~1 KB | 0 KB |
| Last release | recent | 2021 | actively maintained | — |
TL;DR — use this when you have multiple components that need the same online state (the context avoids duplicated polls) and you want actual internet reachability. Use react-detect-offline if you prefer a render-prop API and want zero context plumbing. Use the useNetworkState hook from react-use if navigator.onLine is good enough for your case (it usually isn't).
➔ Open in StackBlitz — a minimal Vite + React + TS demo of the provider + useContext consumer.
Local copy: examples/stackblitz/
is-online— the underlying detection library.- Other utilities by the author: shipx · album-art · movie-info.
- @sindresorhus for
is-online— does all the real work.