rsnext/docs/routing/shallow-routing.md
Luis Alvarez D c6dc34e4d7
[Docs] Focus on useRouter (#14515)
[ch4109]

Closes https://github.com/vercel/next.js/issues/14500

Our current docs for `next/router` use examples from both `useRouter` and `import Router from 'next/router'`, with this PR I'm unifying the API into `useRouter` (`withRouter` is still going to be mentioned multiple times as it is the HOC alternative) and no longer mentioning that you can import a global `Router` object from `next/router`, not sure if I should mention it at least once but that didn't seem to be required.

I also did some structural changes to the docs for `next/router`, now every method starts with a description, then the implementation and explanation of the parameters of the method, and then the usage example, because every method uses the same `Usage` title the hash for them would be something like `#usage`, `#usage-1`, `#usage-2`, e.t.c, so I'm not very happy with this but it looks good.

Feedback wanted 🙏
2020-06-25 23:35:28 +00:00

2.3 KiB

description
You can use shallow routing to change the URL without triggering a new page change. Learn more here.

Shallow Routing

Examples

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.

To enable shallow routing, set the shallow option to true. Consider the following 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('/?counter=10', undefined, { shallow: true })
  }, [])

  useEffect(() => {
    // The counter changed!
  }, [router.query.counter])
}

export default Page

The URL will get updated to /?counter=10. and the page won't get replaced, only the state of the route is changed.

You can also watch for URL changes via componentDidUpdate as shown below:

componentDidUpdate(prevProps) {
  const { pathname, query } = this.props.router
  // verify props have changed to avoid an infinite loop
  if (query.counter !== prevProps.router.query.counter) {
    // fetch data based on the new query
  }
}

Caveats

Shallow routing only works for same page URL changes. For example, let's assume we have another page called pages/about.js, and you run this:

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

Since that's 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.