[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 🙏
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.