Search code examples
javascriptreactjsnext.js

Change URl without page refresh NEXT.JS


I am developing a ecommerce store using NEXT.JS and Redux. So in product listing page, I have sorting select dropdown with Price Low to High, Price High to Low and New Arrivals. Upon selecting this option, I want to change the URL without page refresh and API call should occure. I have tried using below code, but it is not working and page is reloading.

function sortBy(value) {
    router.replace({
        pathname: '/products/'+slug,
        query: { sort: value }
    })

    dispatch(fetchproducts(slug, sort));
}

The above code just refresh the current page and appending sort param to URL.

So is it possible to do it without page refresh like in Flipkart.


Solution

  • With the help of shallow-routing change of URL without doing a page reload is possible. It can be enabled by passing explicit option object as third argument to Router.push, i.e { shallow: true }

    From the docs

    Shallow routing allows you to change the URL without running data fetching methods again, that includes getServerSideProps, getStaticProps, and getInitialProps.

    You'll receive the updated pathname and the query via the router object (added by useRouter or withRouter), without losing state.

    For example, this how you would update the query param sortBy for pathname /products with the help of shallow-routing.

    Router.push({
      pathname: '/products',
      query: { sortBy: 'price' }
    }, 
    undefined, { shallow: true }
    )
    

    But there are a few caveats It is not possible to do shallow-routing between different pages, it works only for same page URL changes. See the caveat section for more details.

    For example, you can update a query param for page /product page, but it won't be possible if you try to do shallow-routing from /product to /product/[slug] because they are two distinct pages.

    // page will reload because shallow-routing not possible between the pages
    Router.push('/product', '/product/some-product?sortBy=price', { shallow: true })