'Next.js Router.push() reloads page automatically

Is there a way to execute a Router.push() without reloading the page using Next.js?

I am using a [...all].js main file for a page that based on the url renders different components, but i want to be able to move between them without triggering a full page reload - it is a multi-step form.

In other words, I want to be able to move between the steps of the form by also updating the URL from 'form/1' to 'form/2'



Solution 1:[1]

This page has more on router

router.push(url, as, options)

url - The URL to navigate to

as - Optional decorator for the URL that will be shown in the browser. Before Next.js 9.5.3 this was used for dynamic routes, check our previous docs to see how it worked

options - Optional object with the following configuration options:

shallow: Update the path of the current page without rerunning getStaticProps, getServerSideProps or getInitialProps. Defaults to false

You don't need to use router.push for external URLs. window.location is better suited for those cases

Solution 2:[2]

This page comes first on Next.js and 'page reloads'. To save others some time troubleshooting, consider this code:

router.push({query: {page: 1}}, undefined, { shallow: true });

It would seem there are some configurations of Next.JS that would make the page reload even if the query is the same as before, which is an easy way towards an infinite cycle of page reloads. Moreover, the browser would also reload unless you explicitly specify the pathname. I see this behavior on my server, but not on my laptop, both of which run Next.js 10.1.3. As far as I can tell, the only difference is there is no base URL set on my laptop, while the server does have a base URL. This remedies the problem:

let routerOpts = {page: 1};
if (!_.isEqual(routerOpts, router.query)) 
  router.push({pathname: router.pathname, query: routerOpts}, undefined, { shallow: true });

As far as I can tell, 'shallow' makes no difference and this works fine as well:

let routerOpts = {page: 1};
if (!_.isEqual(routerOpts, router.query)) router.push({pathname: router.pathname, query: routerOpts})

Solution 3:[3]

I also encounted the above issue, where actually adding {shallow: true} was not good a enough solution.

Depending on the events you have on your form input elements such as: onKeyUp upon hitting the enter key, for example, You may also need to call event.preventDefault() to keep the form from reloading the page and allow router.push() to do it's thing. Yeah, D'oh! ;}

const search = (e) => {
   if ( event.key === 'Enter' && event.target.value) {
      event.preventDefault();
      router.push(`/foo?q=${event.target.value}`, undefined, { shallow: true })
   }
}

return(
  <input 
    ... 
    onKeyPress={search} 
  />
)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Chukwu3meka
Solution 2 Maksym
Solution 3