\n\nBefore moving forward, we recommend you to read Routing Introduction first.
\n
If you want to access the router
object inside any function component in your app, you can use the useRouter
hook, take a look at the following example:
import { useRouter } from 'next/router'\n\nfunction ActiveLink({ children, href }) {\n const router = useRouter()\n const style = {\n marginRight: 10,\n color: router.pathname === href ? 'red' : 'black',\n }\n\n const handleClick = e => {\n e.preventDefault()\n router.push(href)\n }\n\n return (\n <a href={href} onClick={handleClick} style={style}>\n {children}\n </a>\n )\n}\n\nexport default ActiveLink\n
\n\n\n\n
useRouter
is a React Hook, meaning it cannot be used with classes. You can either use withRouter or wrap your class in a function component.
The following is the definition of the router
object returned by both useRouter
and withRouter
:
pathname
: String
- Current route. That is the path of the page in /pages
query
: Object
- The query string parsed to an object. Defaults to {}
asPath
: String
- Actual path (including the query) shown in the browserAdditionally, the Router API
is also included inside the object.
\n\nThe
\nquery
object will be empty during prerendering if the page is statically optimized.
If useRouter
is not the best fit for you, withRouter
can also add the same router
object to any component, here's how to use it:
import { withRouter } from 'next/router'\n\nfunction Page({ router }) {\n return <p>{router.pathname}</p>\n}\n\nexport default withRouter(Page)\n
\nThe API of Router
, exported by next/router
, is defined below.
Handles client-side transitions, this method is useful for cases where next/link
is not enough.
import Router from 'next/router'\n\nRouter.push(url, as, options)\n
\nurl
- The URL to navigate to. This is usually the name of a page
as
- Optional decorator for the URL that will be shown in the browser. Defaults to url
options
- Optional object with the following configuration options:shallow
: Update the path of the current page without rerunning getStaticProps
, getServerSideProps
or getInitialProps
. Defaults to false
\n\nYou don't need to use
\nRouter
for external URLs, window.location is better suited for those cases.
Navigating to pages/about.js
, which is a predefined route:
import Router from 'next/router'\n\nfunction Page() {\n return <span onClick={() => Router.push('/about')}>Click me</span>\n}\n
\nNavigating pages/post/[pid].js
, which is a dynamic route:
import Router from 'next/router'\n\nfunction Page() {\n return (\n <span onClick={() => Router.push('/post/[pid]', '/post/abc')}>\n Click me\n </span>\n )\n}\n
\nYou can use an URL object in the same way you can use it for next/link
. Works for both the url
and as
parameters:
import Router from 'next/router'\n\nconst handler = () => {\n Router.push({\n pathname: '/about',\n query: { name: 'Vercel' },\n })\n}\n\nfunction ReadMore() {\n return (\n <div>\n Click <span onClick={handler}>here</span> to read more\n </div>\n )\n}\n\nexport default ReadMore\n
\nSimilar to the replace
prop in next/link
, Router.replace
will prevent adding a new URL entry into the history
stack, take a look at the following example:
import Router from 'next/router'\n\nRouter.replace('/home')\n
\nThe API for Router.replace
is exactly the same as that used for Router.push
.
Prefetch pages for faster client-side transitions. This method is only useful for navigations without next/link
, as next/link
takes care of prefetching pages automatically.
\n\nThis is a production only feature. Next.js doesn't prefetch pages on development.
\n
import Router from 'next/router'\n\nRouter.prefetch(url, as)\n
\nurl
- The path to a page
inside the pages
directoryas
- Optional decorator for url
, used to prefetch dynamic routes. Defaults to url
Let's say you have a login page, and after a login, you redirect the user to the dashboard. For that case, we can prefetch the dashboard to make a faster transition, like in the following example:
\nimport { useCallback, useEffect } from 'react'\nimport Router from 'next/router'\n\nexport default function Login() {\n const handleSubmit = useCallback(e => {\n e.preventDefault()\n\n fetch('/api/login', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n /* Form data */\n }),\n }).then(res => {\n // Do a fast client-side transition to the already prefetched dashboard page\n if (res.ok) Router.push('/dashboard')\n })\n }, [])\n\n useEffect(() => {\n // Prefetch the dashboard page as the user will go there after the login\n Router.prefetch('/dashboard')\n }, [])\n\n return (\n <form onSubmit={handleSubmit}>\n {/* Form fields */}\n <button type=\"submit\">Login</button>\n </form>\n )\n}\n
\nIn some cases (for example, if using a Custom Server), you may wish to listen to popstate and do something before the router acts on it.
\nYou could use this to manipulate the request, or force a SSR refresh, as in the following example:
\nimport Router from 'next/router'\n\nRouter.beforePopState(({ url, as, options }) => {\n // I only want to allow these two routes!\n if (as !== '/' && as !== '/other') {\n // Have SSR render bad routes as a 404.\n window.location.href = as\n return false\n }\n\n return true\n})\n
\nRouter.beforePopState(cb: () => boolean)
cb
- The function to run on incoming popstate
events. The function receives the state of the event as an object with the following props:url
: String
- the route for the new state. This is usually the name of a page
as
: String
- the url that will be shown in the browseroptions
: Object
- Additional options sent by Router.pushIf the function you pass into beforePopState
returns false
, Router
will not handle popstate
and you'll be responsible for handling it, in that case. See Disabling file-system routing.
Navigate back in history. Equivalent to clicking the browser’s back button. It executes window.history.back()
.
import Router from 'next/router'\n\nRouter.back()\n
\nReload the current URL. Equivalent to clicking the browser’s refresh button. It executes window.location.reload()
.
import Router from 'next/router'\n\nRouter.reload()\n
\nYou can listen to different events happening inside the Router. Here's a list of supported events:
\nrouteChangeStart(url)
- Fires when a route starts to changerouteChangeComplete(url)
- Fires when a route changed completelyrouteChangeError(err, url)
- Fires when there's an error when changing routes, or a route load is cancellederr.cancelled
- Indicates if the navigation was cancelledbeforeHistoryChange(url)
- Fires just before changing the browser's historyhashChangeStart(url)
- Fires when the hash will change but not the pagehashChangeComplete(url)
- Fires when the hash has changed but not the page\n\nHere
\nurl
is the URL shown in the browser. If you callRouter.push(url, as)
(or similar), then the value ofurl
will beas
.
For example, to listen to the router event routeChangeStart
, do the following:
import Router from 'next/router'\n\nconst handleRouteChange = url => {\n console.log('App is changing to: ', url)\n}\n\nRouter.events.on('routeChangeStart', handleRouteChange)\n
\nIf you no longer want to listen to the event, unsubscribe with the off
method:
import Router from 'next/router'\n\nRouter.events.off('routeChangeStart', handleRouteChange)\n
\nIf a route load is cancelled (for example, by clicking two links rapidly in succession), routeChangeError
will fire. And the passed err
will contain a cancelled
property set to true
, as in the following example:
import Router from 'next/router'\n\nRouter.events.on('routeChangeError', (err, url) => {\n if (err.cancelled) {\n console.log(`Route to ${url} was cancelled!`)\n }\n})\n
\nRouter events should be registered when a component mounts (useEffect or componentDidMount / componentWillUnmount) or imperatively when an event happens, as in the following example:
\nimport Router from 'next/router'\n\nuseEffect(() => {\n const handleRouteChange = url => {\n console.log('App is changing to: ', url)\n }\n\n Router.events.on('routeChangeStart', handleRouteChange)\n return () => {\n Router.events.off('routeChangeStart', handleRouteChange)\n }\n}, [])\n
"},"__N_SSG":true}