Skip to content

Add experimental.useOffline — offline detection, retry, and useOffline() hook #701

@github-actions

Description

@github-actions

Upstream

Summary

Next.js added a new experimental.useOffline flag that provides two capabilities:

1. Offline retry for navigations, server actions, and prefetches

When a fetch() rejects due to a network error (not abort/timeout), the request blocks until connectivity is restored and then retries automatically, instead of falling back to MPA navigation or surfacing an error.

  • New packages/next/src/client/components/offline.ts module owns all offline state: detection, polling with exponential backoff (500ms → 1s → 2s → 3s cap), and connectivity checks via HEAD requests.
  • fetchServerResponse (navigation) catches network errors, calls checkOfflineError()waitForConnection() → retries.
  • fetchServerAction (server actions) does the same — safe to replay because the rejection means the request never reached the server.
  • Browser offline/online events feed into the polling loop. Successful fetches from any code path short-circuit via notifyOnline().
  • Gated behind process.env.__NEXT_USE_OFFLINE with lazy require() calls.

2. useOffline() hook via next/offline

  • New next/offline export path (offline.js, offline.d.ts).
  • useOffline() hook returns true when offline, powered by OfflineProvider rendered inside the app router.
  • Uses useState + useOptimistic so value updates even during blocked transitions.
  • Module-level dispatchOfflineChange() bridges from the offline detection module into React state via startTransition.

Impact on vinext

  1. New shim needed: next/offline → export useOffline() hook. Needs to be added to the shim map in index.ts.
  2. Config flag: experimental.useOffline needs to be recognized if vinext processes next.config.
  3. Client-side router changes: The offline retry logic lives in the client router reducer layer. If vinext ships its own client-side navigation (vs. delegating to Next.js client code), this needs to be replicated. If vinext re-exports Next.js client components, this may come for free with the flag.
  4. OfflineProvider in app router tree: The provider wraps the router content — relevant if vinext constructs the app router React tree.
  5. Prefetch scheduler integration: notifyOnline() calls pingPrefetchScheduler() to resume prefetches after reconnection.

Suggested approach

Start with the shim for next/offline that exports a no-op useOffline() returning false. The full offline retry behavior is complex client-side router logic that can be deferred until the feature stabilizes (it's behind experimental).

Metadata

Metadata

Assignees

No one assigned

    Labels

    nextjs-trackingTracking issue for a Next.js canary change relevant to vinext

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions