Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

249
Views
Next.js behavior on back button pressed

I have a page I am trying to fix in order to keep scroll position when user presses back button (browser). Let's say I have a component called list, where I show the user some products. To see all the products the user can scroll down the list component. When the user clicks on some product, the application redirects the user to the detail component. Then when the user tries to go back to the list, hits the back button of the browser, the list component gets rendered and it seems like it scrolls to top automatically.

As far as I know, pressing the back button of the browser triggers a window.history.back() action, nothing else happens.

For a solution, I have implemented a variable in the context of my application that saves the scrollY value and then, in the componentWillMount (or useEffect) of the component I am trying to render (list component), I set the scroll position to the value set in the context.

Details of my solution are here, as I have based my entire code in this stack overflow's post: How to change scroll behavior while going back in next js?

I have checked the value using some logs and the scroll position is saved correctly in the context, however, as I am using a window event listener, it sets the value to zero just after the list component is rendered.

In my code I am not using any kind of scroll configuration, so I was wondering if that behavior is some sort of default for either Next.js or react. It happens when the user hits the back button of the browser, but I am a newbie to next and I don't know if I am missing something or what, I don't even know if this issue has something to do with React or Next.js itself.

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

This gist may be of assistance as it includes a custom hook to manage scroll position: https://gist.github.com/claus/992a5596d6532ac91b24abe24e10ae81

import { useEffect } from 'react';

import Router from 'next/router';

function saveScrollPos(url) {
    const scrollPos = { x: window.scrollX, y: window.scrollY };
    sessionStorage.setItem(url, JSON.stringify(scrollPos));
}

function restoreScrollPos(url) {
    const scrollPos = JSON.parse(sessionStorage.getItem(url));
    if (scrollPos) {
        window.scrollTo(scrollPos.x, scrollPos.y);
    }
}

export default function useScrollRestoration(router) {
    useEffect(() => {
        if ('scrollRestoration' in window.history) {
            let shouldScrollRestore = false;
            window.history.scrollRestoration = 'manual';
            restoreScrollPos(router.asPath);

            const onBeforeUnload = event => {
                saveScrollPos(router.asPath);
                delete event['returnValue'];
            };

            const onRouteChangeStart = () => {
                saveScrollPos(router.asPath);
            };

            const onRouteChangeComplete = url => {
                if (shouldScrollRestore) {
                    shouldScrollRestore = false;
                    restoreScrollPos(url);
                }
            };

            window.addEventListener('beforeunload', onBeforeUnload);
            Router.events.on('routeChangeStart', onRouteChangeStart);
            Router.events.on('routeChangeComplete', onRouteChangeComplete);
            Router.beforePopState(() => {
                shouldScrollRestore = true;
                return true;
            });

            return () => {
                window.removeEventListener('beforeunload', onBeforeUnload);
                Router.events.off('routeChangeStart', onRouteChangeStart);
                Router.events.off('routeChangeComplete', onRouteChangeComplete);
                Router.beforePopState(() => true);
            };
        }
    }, [router]);
}
about 4 years ago · Juan Pablo Isaza Report

0

Looking at your url, using shallow routing could solve the problem. Where the URL will get updated. And the page won't get replaced, only the state of the route is changed. So you can change your logic according to that.

A good example is in the official documentation: https://nextjs.org/docs/routing/shallow-routing

And you might use display: 'hidden' to hide and show your components conditionally according to your state!

It's a way around but it could be even more useful depending on your exact situation !

about 4 years ago · Juan Pablo Isaza Report

0

After looking for another solution that does not use the window.scroll and similar methods, I have found a solution.

1st solution (worked, but for me that I have an infinite list that is loaded via API call, sometimes the window.scroll method wasn't accurate): I take the window.scrollY value and set it in the session storage, I did this before leaving the list page, so in the details page, if user hits the back button, at the moment the page is loading, I get the Y value from session storage and use the window.scroll method to force the page to scroll to the previously configured value. As I mentioned earlier, this worked, but in my case, I have a list that is populated from an async API call, so sometimes the page loaded without all the images and the scroll was already configured, then the images and data were loaded and the user ended up seeing some other place in the page rather than the desire position.

2nd solution: In my case we are talking about a e commerce app, so I found this solution useful as it focuses in a particular item with its corresponding ID instead of the Y coord of the window. Scroll Restoration in e commerce app

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!