next.js: Next 12.3.1 breaks smooth-scrolling, change made in 12.3.1-canary.4, woks in 12.3.1-canary.3 and before
Verify canary release
- I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System: Platform: darwin Arch: x64 Version: Darwin Kernel Version 21.6.0: Sat Jun 18 17:07:25 PDT 2022; root:xnu-8020.140.41~1/RELEASE_X86_64 Binaries: Node: 16.13.0 npm: 8.1.0 Yarn: 3.2.3 pnpm: N/A Relevant packages: next: 12.3.1-canary.3 eslint-config-next: N/A react: 0.0.0-experimental-8951c5fc9-20220915 react-dom: 0.0.0-experimental-8951c5fc9-20220915
What browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
Describe the Bug
@timneutkens @cramforce The following commit completely disables smooth-scrolling- https://github.com/vercel/next.js/pull/40642. We use the following custom hook here to trigger the scroll-behaviour we want. We do not have anything else like a global css which sets the scroll-behaviour on html.
The scroll-behaviour becomes non-deterministic in version 12.3.1-canary.4, the previous version 12.3.1-canary.3 works perfectly. The latest release 12.3.1 is also affected.
import { MittEmitter } from '@app/render-utils';
import { useEffect } from 'react';
/**
* The scrolling behavior is always set to smooth, when a page mounts.
* On route change, the scrolling behavior switches to auto before it snaps back to smooth.
*
* Note:
* Do not use the nextJs hook "use-router" in this custom hook; constant re-renders get executed;
* Unfortunately, it seems there are some bugs in the router implementation (asPath / hash-change).
*
* Instead, the nextJs router events object from the _app component is given as an argument.
*/
export const useSmoothScroll = (events: MittEmitter) => {
const setSmoothScroll = (isSmooth: boolean) => {
document.documentElement.style.scrollBehavior = isSmooth
? 'smooth'
: 'auto';
};
useEffect(() => {
setSmoothScroll(true);
const handleRouteChangeStart = () => setSmoothScroll(false);
const handleRouteChangeComplete = () => setSmoothScroll(true);
events.on('routeChangeStart', handleRouteChangeStart);
events.on('routeChangeComplete', handleRouteChangeComplete);
return () => {
events.off('routeChangeStart', handleRouteChangeStart);
events.off('routeChangeComplete', handleRouteChangeComplete);
};
}, []);
};
Can you please provide feedback on how to enable scroll-behaviour using the hook again? Thx!
Expected Behavior
Identical behaviour like in 12.3.1-canary.3
Link to reproduction
I will not create a reproducer for things y break; and smooth-scrolling is something which broke a few times in the past.
To Reproduce
Use the hook from above in _app.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 10
- Comments: 18 (17 by maintainers)
Commits related to this issue
- Force reflow when setting scrollBehavior (#43673) fixes https://github.com/vercel/next.js/issues/40719 — committed to vercel/next.js by jankaifer 2 years ago
@wyattjoh Here is a video with your reproducer in action illustration the problem. I adjusted the height of the sections to make it clear. Imagine when you have larger pages such as blog posts or a e-commerce pages showing dozen of items, changing a route causes a smooth transition to the top, which is really annoying, and this has to be immediate.
https://user-images.githubusercontent.com/301689/205177206-ac9f05bf-2a71-49b3-a19e-a09dc4206f5f.mov
Thx!
@timneutkens I disabled the hook, and configured scrolling with css. The result was really not the same, compared with the hook enabled using a nightly version of Next right before the change landed. For the next two weeks I’m traveling without any device on hand, but I can provide a reproducer afterwards. Thx for looking into that!