cloudflare / cloudflare/vinext
App Router navigation scroll: adopt the new scroll handler (remove legacy findDOMNode-based path)
- Dominant language
- TypeScript
- Stars
- 8.8k
- Forks
- 406
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 120
Description
## Upstream change
`[fragment-scroll] Remove config.experimental.appNewScrollHandler` (#95602) — https://github.com/vercel/next.js/commit/2c047359448d701c3ef6638e1f06f5e866993fdb
Next.js graduated the new scroll-on-navigation handler and deleted the legacy path entirely. The `experimental.appNewScrollHandler` flag, its define-env var (`__NEXT_APP_NEW_SCROLL_HANDLER`), and the old `InnerScrollAndFocusHandlerOld` class in `layout-router.tsx` are removed (~191 lines deleted). This also removes the last `ReactDOM.findDOMNode` usage in `layout-router.tsx` (the `__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE.findDOMNode` shim and the `shouldSkipElement`/`rectProperties` viewport helpers that went with it).
## What changed
- Deleted: `enableNewScrollHandler` env gate, `findDOMNode` wrapper, `shouldSkipElement`, `rectProperties`, and the entire `InnerScrollAndFocusHandlerOld` React.Component.
- The new handler (which finds the scroll target without `findDOMNode`, e.g. via refs / hash fragment DOM lookup) is now the only code path for post-navigation scroll and focus.
- Config/schema plumbing removed: `next_config.rs`, `config-schema.ts`, `config-shared.ts`, `config.ts`, `define-env.ts`.
## Why it matters for vinext
vinext reimplements App Router client-side navigation, including scroll-and-focus restoration after a navigation. If vinext modeled its scroll handling on the legacy `InnerScrollAndFocusHandlerOld` behavior (findDOMNode-based target resolution, sticky/fixed-position skipping via `shouldSkipElement`), that behavior is now dead in Next.js and the new handler is authoritative. We should verify vinext's scroll handler matches the new behavior, does not depend on `findDOMNode`, and does not read the removed `__NEXT_APP_NEW_SCROLL_HANDLER` / `experimental.appNewScrollHandler` config.
Note: this is distinct from #2810 (scroll-padding-top viewport boundary) — that is a specific behavior gap; this is about which handler implementation is the source of truth.
## Action
- Confirm vinext's post-navigation scroll/focus logic tracks the new handler, not the removed legacy one.
- Ensure vinext does not expose or read `experimental.appNewScrollHandler` / `__NEXT_APP_NEW_SCROLL_HANDLER`.
- Verify no reliance on `ReactDOM.findDOMNode` for scroll target resolution.
## References
- https://github.com/vercel/next.js/commit/2c047359448d701c3ef6638e1f06f5e866993fdb (#95602)
Contributor guide
Research direction
Locate vinext's post-navigation scroll and focus entry points, then compare their behavior with Next.js's new handler described in the referenced commit. Search the repository for experimental.appNewScrollHandler, __NEXT_APP_NEW_SCROLL_HANDLER, and findDOMNode. Done means the legacy path and config references are absent and the new navigation behavior is verified by the relevant tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100