AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

`Scroll: False` Not Preserved Across Async PPR Retry Navigations (Force-Dynamic Pages)

On force-dynamic pages using PPR, router.replace(url, { scroll: false }) loses the scroll:false option when an async retry navigation occurs due to a tree mismatch. The server-patch reducer hardcodes scroll-to-top, causing the page to jump to the top on every query parameter change after a prefetch has populated the optimistic route cache.

highConfidence 92%Next.jsAffected V16.1.6Affected V16.3.0-Canary.52

Origin Analysis

server-patch-reducer.js hardcodes ScrollBehavior.Default on retry navigation, so the original scroll:false intent from router.replace is never threaded through the async retry path.
1. Build and start the reproduction app in production mode: npm i && npm run prod 2. Open http://localhost:3000 3. Scroll down to the Filters section at the bottom 4. Tick one colour checkbox — the page scrolls back to the top.

Fixing Code Block

Edge Case Audit

This patch modifies dist/ files directly, so it will be overwritten on any rebuild or package update; apply via patch-package or move to source. If scrollBehavior is undefined for older cached actions, the fallback keeps previous behavior, but test concurrent navigations to ensure no stale scrollBehavior is applied across different retries. Rolling back to an unpatched Next.js version will reintroduce the bug; pin the patched version until an official fix lands. Also verify that gestures and hard retries still behave correctly when scrollBehavior is explicitly set.

Ecosystem Topology