nextjs scrollRestoration
-
By default nextjs auto scroll to the top when the router changes. Most of time, this what we wanted, but sometimes, we would like scroll could be restored, especially, user uses "Back" or "Forward" navigation.
Here is my way:- set scrollRestoration to true. in next.config.js
- use javascript to scroll to the top when the page is newly loaded
isNavigation = false; handleRouteChange = (url) => { console.log("User navigated to:", url); gtag.pageview(url); if (!this.isNavigation) { console.log("scroll to top when load a new page"); // console.log("URL", url); this.timerHandle = setTimeout(() => { window.scrollTo(0, 0); this.timerHandle = 0; }, 100); this.isNavigation = false; } NProgress.done(); }; handleBeforePopState = ({ url, as, options }) => { console.log("User navigated backwards or forwards"); this.isNavigation = true; // Do something when user navigates back or forward return true; }; handleStart = (url) => { // console.log(`Loading: ${url}`); NProgress.start(); }; handleStop = () => { NProgress.done(); }; componentDidMount = async () => { Router.events.on("routeChangeComplete", this.handleRouteChange); Router.events.on("routeChangeStart", this.handleStart); Router.events.on("routeChangeError", this.handleStop); Router.beforePopState(this.handleBeforePopState); }; componentWillUnmount = () => { Router.events.off("routeChangeComplete", this.handleRouteChange); Router.events.off("routeChangeStart", this.handleStart); Router.events.off("routeChangeError", this.handleStop); Router.beforePopState(() => true); if (this.timerHandle) { // Yes, clear it clearTimeout(this.timerHandle); this.timerHandle = 0; } };