Next.js - Shallow routing with dynamic routes Next.js - Shallow routing with dynamic routes reactjs reactjs

Next.js - Shallow routing with dynamic routes


I think this is the expected behavior because you are routing to a new page. If you are just changing the query parameters shallow routing should work for example:

router.push('/?counter=10', undefined, { shallow: true })

but you are using route parameters

router.push(  '/post/[...slug]',  '/post/2020/01/01/hello-world',  { shallow: true });

That indicates you are routing to a new page, it'll unload the current page, load the new one, and wait for data fetching even though we asked to do shallow routing and this is mentioned in the docs here Shallow routing caveats.

By the way, you say "the page is refreshed" but router.push doesn't refresh the page even when used without shallow: true. It's a single page app after all. It just renders the new page and runs getStaticProps, getServerSideProps, or getInitialProps.


Shallow Routing Caveats

Shallow Routing gives you the ability to update pathname or query params without losing state i.e., only the state of route is changed.. But the condition is, you have to be on the same page(as shown in docs Caveats image).

For that you have to pass the second arg to router.push or Router.push as undefined. Otherwise, new page will be loaded after unloading the first page and you won't get the expected behavior.

I mean shallow routing will no longer be working in terms of pathname changing and that's because we chose to load a new page not only the url. Hope this helps 😉

Example

import { useEffect } from 'react'import { useRouter } from 'next/router'// Current URL is '/'function Page() {  const router = useRouter()  useEffect(() => {    // Always do navigations after the first render    router.push('/post/[...slug]', undefined, { shallow: true })  }, [])  useEffect(() => {    // The pathname changed!  }, [router.pathname ])}export default Page


Actually, based on the docs description, I believe you used this push function wrongly. See the following codes that come from docs:

import Router from 'next/router'Router.push(url, as, options)

And the docs said:

  • url - The URL to navigate to. This is usually the name of a page
  • as - Optional decorator for the URL that will be shown in the browser. Defaults to url
  • 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

It means you should pass the exact URL as the first parameter and if you wanna show it as decorating name pass the second parameter and for the third just pass the option, so you should write like below:

router.push(  '/post/2020/01/01/hello-world',  undefined,  undefined);

For the shallow routing you should use the exact example:

router.push('/?counter=10', undefined, { shallow: true });

In fact, with your code, you create a new route and it is inevitable to refreshing.