How to use the Next.js Router
By Flavio Copes
Learn how to use the Next.js Router from next/router to change routes programmatically, calling useRouter to access the push() and prefetch() methods.
To change routes programmatically in Next.js, you use the Router provided by the next/router package: you call the useRouter() hook in your component, and then call methods like push() on the router object it returns.
In linking two pages in Next.js using Link we saw how to use the Link component to declaratively handle routing in Next.js apps.
It’s really handy to manage routing in JSX, but sometimes you need to trigger a routing change programmatically. Think of what happens after a form submission: there’s no link to click, your code decides where to go next.
Here’s an example of accessing the router:
import { useRouter } from 'next/router'
export default () => {
const router = useRouter()
//...
}
Once we get the router object by invoking useRouter(), we can use its methods.
This is the client side router, so methods should only be used in frontend facing code. The easiest way to ensure this is to wrap calls in the
useEffect()React hook, or insidecomponentDidMount()in React stateful components.
The ones you’ll likely use the most are push() and prefetch().
Navigating with push()
push() allows us to programmatically trigger a URL change, in the frontend:
router.push('/login')
It also accepts an object, which is handy when you have query parameters:
router.push({
pathname: '/search',
query: { term: 'nextjs' }
})
This navigates to /search?term=nextjs.
If you don’t want the current page to stay in the browser history, use replace() instead. It works like push(), but the back button skips the replaced page. That’s what you want after a login redirect, for example:
router.replace('/dashboard')
Prefetching a URL
prefetch() allows us to programmatically prefetch a URL, useful when we don’t have a Link tag which automatically handles prefetching for us:
router.prefetch('/login')
Full example:
import { useRouter } from 'next/router'
export default () => {
const router = useRouter()
useEffect(() => {
router.prefetch('/login')
}, [])
}
Note that prefetch() only does something in production builds. In development it’s a no-op, so don’t be surprised if you see no network activity there.
Reading the current route
The router also tells you where you are. router.pathname holds the current path, and router.query holds the query string parameters as an object.
Be careful with router.query on statically generated pages: during the first render it’s an empty object, and it gets filled right after hydration. If you read query parameters in an effect, check router.isReady first:
useEffect(() => {
if (!router.isReady) return
console.log(router.query.term)
}, [router.isReady])
You can also use the router to listen for route change events.
Related posts about next: