While using Next.js, I encountered an issue where opening a new page would maintain the scroll position from the previous page. For instance, if I had scrolled to the bottom of a product listing page and clicked on a specific product, the product details page would open with the scroll position still at the bottom.
I am seeking a solution to automatically scroll to the top when navigating to a new page in Next.js. How can I implement this scroll-to-top functionality?
Below are some approaches I have attempted:
Attempt 1
import { useEffect } from 'react';
import { useRouter } from 'next/router';
const ProductDetails = () => {
const router = useRouter();
useEffect(() => {
const handleRouteChange = () => {
window.scrollTo(0, 0);
};
router.events.on('routeChangeComplete', handleRouteChange);
return () => {
router.events.off('routeChangeComplete', handleRouteChange);
};
}, [router]);
return (
// Product details code goes here
);
};
export default ProductDetails;
Attempt 2
import { useEffect } from 'react';
import { useRouter } from 'next/router';
const ProductDetails = () => {
const router = useRouter();
useEffect(() => {
window.scrollTo(0, 0);
}, [router.pathname]);
return (
// Product details code goes here
);
};
export default ProductDetails;
Attempt 3
import { useEffect } from 'react';
import { useRouter } from 'next/router';
const ProductDetails = () => {
const router = useRouter();
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return (
// Product details code goes here
);
};
export default ProductDetails;
Attempt 4
useEffect(() => {
// The scrollTo behavior is set on the container element with the id "top"
const topElement = document.getElementById("top");
topElement?.scrollIntoView({ behavior: "smooth" });
}, [router.pathname]);
The solutions above worked for other routes, but they did not work for dynamic routes like /products/product/[slug]
, even when adding the slug to the dependency array in useEffect.
Note: I also tried placing the code directly into the component where I wanted the screen to scroll to the top, but it did not achieve the desired outcome.
Edited: Code example added for reference