Next.js 16 SSR and PWA Caching Bug Emerges
An engineering discussion has highlighted a bug in Next.js 16 causing infinite loading issues on mobile and PWA clients when using the App Router with Supabase SSR. The likely cause is manual service worker caching interfering with React Server Components (RSC) and Flight data. The issue underscores the complexities of combining modern SSR, RSC, and PWA caching strategies.
The conflict arises from the intricate interaction between Next.js's four distinct caching layers. These include Request Memoization for deduplicating function calls within a single render, a persistent Data Cache for fetch requests, the Full Route Cache for server-rendered HTML and RSC payloads, and a client-side Router Cache for seamless navigation. A manual service worker, if not configured precisely, can inadvertently cache the RSC payload (also known as "Flight data"), leading to stale data being served on subsequent visits and causing an infinite load state. This issue is compounded by the App Router's default behavior, which aggressively caches to enhance performance. While developers can opt-out, understanding the nuances of each layer—like the 30-second duration of the client-side Router Cache versus the persistent Full Route Cache—is critical for debugging. The problem reported involves a manual service worker implementing a "NetworkFirst" strategy for most requests, which likely caches internal Next.js data requests incorrectly. React Server Components themselves introduce a new paradigm, running exclusively on the server and not increasing the client-side JavaScript bundle. This server-centric approach simplifies data fetching but requires careful management of the boundary between server and client components, marked by the `"use client"` directive. The bug highlights a scenario where this boundary is blurred by improper caching, causing the client to receive mismatched or outdated component data. Supabase's SSR library, `@supabase/ssr`, is designed to manage authentication and sessions across this client-server boundary using cookies and middleware. The infinite loading screen often points to a failure in this session refresh mechanism, where the middleware can't validate the user, and the PWA's cached shell doesn't know how to recover. Supabase explicitly recommends using their SSR package and correctly implementing middleware to refresh tokens and protect routes. The Next.js team has been actively refining caching APIs. Next.js 16, for instance, introduced more explicit cache controls and an overhaul of the routing and navigation system to reduce network transfer sizes through layout deduplication. However, some developers have noted that any use of dynamic functions like `headers()` or `cookies()` can disable caching for an entire route, forcing a fallback to dynamic rendering, which complicates optimization efforts. Previous versions have also seen similar infinite loading issues, particularly with Suspense boundaries and client component hydration. These past incidents often related to the amount of data passed from server to client components or hydration mismatches that were difficult to reproduce locally. The current bug with PWA caching appears to be a new permutation of this underlying architectural complexity.