Next.js useOffline floods dev with HEAD polls

Local dev with useOffline on spams HEAD then GET every 500ms. Gate experimental.useOffline to Vercel preview and production only.

Sander Korf2 min read
nextjsvercel

Instant Navigations on Vercel wants experimental.useOffline in production so a tab can recover when connectivity blips. Fair. What is less fair is what happens when that flag also lives in the shared @repo/nextjs base config your laptop imports for pnpm dev.

Leave the browser tab open on localhost and the terminal turns into a metronome. HEAD /. GET / with rsc:1. Again. Five hundred milliseconds, then three seconds, then back. Offline connectivity probes, doing their job, except there is no Instant Nav resilience to win on my machine. Just log noise and the feeling that something is broken when nothing is.

The probes are not random. Next.js 16 wires useOffline into a client-side reachability check for deployed Instant Nav. Locally, VERCEL_ENV is unset or development. The flag still reads as on because the config never asked where it was running. Dev and prod shared one boolean. My terminal paid the price.

The fix is boring and correct: only enable offline mode where Instant Nav actually ships.

export function shouldUseOffline(vercelEnv: string | undefined = process.env.VERCEL_ENV): boolean {
	return vercelEnv === 'preview' || vercelEnv === 'production';
}

Wire that into next.config so experimental.useOffline is conditional. Preview and production keep the resilience path. Local pnpm dev stays quiet. Unset VERCEL_ENV stays off. Development stays off.

I still want one shared base config across storefront apps. I just stopped treating Vercel-only flags as always-on constants. If the feature exists for deployed tabs, gate it on deployed environments. Your future self greps fewer repeating HEAD lines.


Happy coding! Sander