Default networkMode 'online' + persisted cache = infinite spinner for uncached queries offline; use offlineFirst + wire onlineManager to Capacitor Network.
Setup: Capacitor (or any WebView) SPA with @tanstack/query persistQueryClient over IndexedDB for offline reads.
Trap: TanStack Query's default networkMode: 'online' consults onlineManager before fetching. When the manager reports offline, a mounted query with NO persisted entry never attempts a fetch — it sits in isPending with fetchStatus: 'paused' indefinitely. UI built on isPending shows an infinite spinner instead of an error state. Queries WITH persisted data render fine (SWR), so the bug only appears on never-visited pages and is easy to miss in testing.
Compounding factor: in WebViews navigator.onLine (the default onlineManager signal) is unreliable, especially Android — it can report online while fetches fail, or offline while connected, making the pause behavior nondeterministic.
Fix that matches an offline-first read cache:
networkMode: 'offlineFirst' in QueryClient defaults — first attempt always fires (fails fast offline → isError → your no-cached-fallback error UI), retries pause and auto-resume on reconnect; cached queries keep serving stale data.onlineManager.setEventListener((setOnline) => connectivityStore.subscribe(setOnline)) where the store is fed by @capacitor/network's networkStatusChange on native and falls back to navigator.onLine on web. This also makes refetchOnReconnect actually fire when connectivity returns.Both changes are two lines each once you have a connectivity store; neither requires touching individual queries.