docs/01-app/03-api-reference/05-config/01-next-config-js/useOffline.mdx
The useOffline configuration option enables offline connectivity detection and automatic retry of failed navigation, prefetch, and Server Action requests. When enabled, it also exposes the useOffline hook for reading the current offline state from Client Components.
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
useOffline: true,
},
}
export default nextConfig
module.exports = {
experimental: {
useOffline: true,
},
}
When enabled, Next.js will:
offline and online events to track connectivity.HEAD requests with backoff while offline.useOffline hook available from next/offline.The offline state is entered through one of two paths:
window.addEventListener('offline', ...) listener. When the OS reports the network interface as down, the offline state flips on immediately.fetch() rejects with a non-abort, non-timeout error calls into the offline module. This catches the case where the browser still reports navigator.onLine === true but the actual request cannot reach the origin (captive portal, broken DNS, dead upstream).Once in the offline state, a polling loop tries to confirm that connectivity has returned.
Each check issues a single HEAD request to the current page's URL with the RSC header set, the same endpoint navigations use. The request is aborted after 200 ms.
Two outcomes count as "online":
Any other rejection schedules the next check. A successful framework fetch (navigation, prefetch, Server Action) during the offline period also flips the state back to online.
Delays between checks are stepped, not exponential, and capped at 3 seconds:
| Attempt | Delay before next check |
|---|---|
| 1 | 500 ms |
| 2 | 1 s |
| 3 | 2 s |
| 4 and after | 3 s |
The browser's online event short-circuits the current wait and runs a connectivity check immediately. Reconnection is detected without waiting for the next scheduled tick.
The polling loop never gives up on its own. It continues at the 3-second cap until a check succeeds or the page unloads. A device that goes offline for hours and then regains connectivity will have its polling loop resume and resolve normally.
While the offline state is active, any navigation, prefetch, or Server Action waits for the next connectivity check to succeed, whether it was newly issued or already in flight when the connection dropped. When the check succeeds, the request runs once; no extra backoff applies.
If it fails with a network error, the app re-enters the offline state and the polling loop starts again.
A single client does not produce a runaway burst of traffic against its origin:
fetch() rejects locally at the browser's network layer. The request never reaches the origin.HEAD request at a time, with delays capped at 3 seconds. No other framework requests are sent to the origin during the offline period.In practice, this feature is unlikely to flood your server. The only extra traffic it generates per offline user is the HEAD polling, which stops as soon as connectivity returns. Prefetches, Server Actions, and navigations fire the same number of times they would have without an outage, just delayed.
| Version | Changes |
|---|---|
v16.x.0 | experimental.useOffline configuration option introduced. |