The functionality to scroll to the top of the page is not functioning properly in Next.js when navigating to a new page using the Link

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

Answer №1

After much exploration, I stumbled upon a solution that brought a smile to my face.

The issue wasn't with the Next.js components themselves. It turned out to be a problem with the predefined CSS in the global.css file.

By default, Next.js' global.css includes a significant amount of CSS code. One particular section defines styling for the body and HTML tags:

html,body {
  max-width: 100vw;
  overflow-x: hidden;
}

Once I removed the overflow-x: hidden from the html/body rule, everything started functioning as expected.

I want to express my gratitude to @divine for their insightful answer on a separate Stack Overflow question addressing the same issue. You can find their response here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for passing down props or all the properties of an object to create a dynamic component

I am facing an issue with a v-for loop in my project. The loop is supposed to iterate through objects in a list of todos fetched from the backend. These objects are then passed down to a child component, which displays each todo individually. However, I ha ...

Refresh a particular element using javascript

I'm new to Javascript and I am trying to refresh a specific element (a div) using only Javascript when that div is clicked. I came across the location.reload() function, but it reloads the entire page which doesn't fit my requirements. Upon clic ...

Tips for embedding Javascript code within the window.write() function

I have a JavaScript function that opens a new window to display an image specified in the data variable. I want the new window to close when the user clicks anywhere on it. I've tried inserting some JavaScript code within window.write() but it doesn&a ...

Integrating Excel into a webpage - is it possible?

Currently facing an issue on my website. I'm trying to open a 'file://' URL directly with the <a href=""> element in a browser, but it's prohibited. I'm searching for a plugin or similar solution that can enable me to execut ...

Using Angular and Typescript to implement a switch case based on specific values

I am attempting to create a switch statement with two values. switch ({'a': val_a,'b': val_b}){ case ({'x','y'}): "some code here" break; } However, this approach is not functioning as expected. ...

Creating a stylish zebra pattern using JCrop on the cropping window

Lately, while using jquery jcrop, I've noticed a peculiar design appearing on the cropping window. The details of this pattern are unclear to me. What could be the reason behind the zebra-like pattern visible on the cropping window? Is there any spec ...

Add the hue value from Hue into the Chromajs HSL state value

My objective is to dynamically change the background color of a div based on user input. I plan to assign the user's input as the value of the state key hue, and then set another state key called color to hold the HSL representation of the hue using C ...

I'm having trouble getting Socket.io to function properly with my Node/Express application

Using openshift with express, I have been experiencing difficulties configuring socket.io. No matter what adjustments I make, it seems to disrupt my application. What could be the issue? Interestingly, when I disable the sections related to socket.io, the ...

The back-end code on the server is unable to identify the variable in my req.body, as it is being flagged

At the moment, I am in the process of developing a web application that needs to transmit data from the client side to the server side whenever a specific button is clicked. However, when I click the button, the terminal consistently informs me that the va ...

The typography text exceeds the boundaries of the Material-UI CardContent

In the React Material-UI framework, I am working with a CardContent component that looks like this: <CardContent className={classes.cardContent}> <Typography component="p" className={classes.title} variant="title"> {this.props.post.title ...

The q library ensures that a value is delivered to the done method

I am seeking to understand the purpose and usage of the `done` method in the Q library promises. If `done` is able to receive a value or function through `resolve` or `reject`, could someone clarify how the `done` method is invoked and how arguments can ...

Is there a way to convert HTML into a structured DOM tree while considering its original source location?

I am currently developing a user script that is designed to operate on https://example.net. This script executes fetch requests for HTML documents from https://example.com, with the intention of parsing them into HTML DOM trees. The challenge I face arise ...

Learn the process of automatically copying SMS message codes to input fields in Angular17

After receiving the first answer, I made some changes to the code. However, when testing it with Angular, I encountered several errors. How can I resolve these issues? TS: async otpRequest() { if ('OTPCredential' in window) { const ab ...

Assign a unique ID to each Angular Material checkbox

Presently, I am facing an issue: I am required to generate md-checkboxes from a Database. The implementation is successful using ng-repeat. However, I am encountering difficulties in fetching the data from these checkboxes. Each entry in the Database has ...

Tips on preserving a dynamic web page within a Cordova application

I have developed a project and To Do list App that operates on a single HTML page with just an "add To Do list" button. Users can click on this button to create a To Do list and add tasks within it, all of which are dynamically generated as HTML elements. ...

When moving from Babel version 5.8.35 to 6.0.0, be prepared for app.js to throw a SyntaxError and encounter an unexpected token during compilation

Currently, I am in the process of enhancing my ReactJS components using webpack. However, I have encountered a hurdle while trying to transition from babel version 5 to 6. Upon attempting the upgrade, it resulted in a stack trace error within my app.js cl ...

Tips for retrieving the most recent number dynamically in a separate component without needing to refresh the page

Utilizing both the Helloworld and New components, we aim to store a value in localStorage using the former and display it using the latter. Despite attempts to retrieve this data via computed properties, the need for manual refreshing persists. To explore ...

Tips for customizing the checked color of Material UI Radio buttons

If I want my radio button to be green instead of the default options (default, primary, secondary), how can I achieve that? I attempted to override the color using the classes prop like this: const styles = theme => ({ radio: { colorPrimary: { ...

Removing a dynamic TypeScript object key was successful

In TypeScript, there is a straightforward method to clone an object: const duplicate = {...original} You can also clone and update properties like this: const updatedDuplicate = {...original, property: 'value'} For instance, consider the foll ...

What is the best way to incorporate CSS into JavaScript code?

Here is the code I am working with: <script type = "text/javascript"> function pic1() { document.getElementById("img").src = "../images/images/1.png"; } function pic2() { document.getEl ...