Note: You are viewing the new Next.js documentation. The old docs are still available here.

Shallow Routing

Examples

Shallow routing allows you to change the URL without running 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', null, { shallow: true })
  }, [])

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

export default Page

If you don't need to add the router object to the page, you can also use the Router API directly, like so:

import Router from 'next/router'
// Inside your page
Router.push('/?counter=10', null, { shallow: true })

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 permalink

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 call getInitialProps even though we asked to do shallow routing.