diff --git a/docs/advanced-features/custom-server.md b/docs/advanced-features/custom-server.md
index 01910f7aec1a1..f1ef1fb01c684 100644
--- a/docs/advanced-features/custom-server.md
+++ b/docs/advanced-features/custom-server.md
@@ -98,4 +98,4 @@ module.exports = {
> Note that `useFileSystemPublicRoutes` disables filename routes from SSR; client-side routing may still access those paths. When using this option, you should guard against navigation to routes you do not want programmatically.
-> You may also wish to configure the client-side Router to disallow client-side redirects to filename routes; for that refer to [`Router.beforePopState`](/docs/api-reference/next/router.md#router.beforePopState).
+> You may also wish to configure the client-side router to disallow client-side redirects to filename routes; for that refer to [`router.beforePopState`](/docs/api-reference/next/router.md#router.beforePopState).
diff --git a/docs/api-reference/next/router.md b/docs/api-reference/next/router.md
index b22afe6137ca8..cd474b4112735 100644
--- a/docs/api-reference/next/router.md
+++ b/docs/api-reference/next/router.md
@@ -37,7 +37,7 @@ export default ActiveLink
> `useRouter` is a [React Hook](https://reactjs.org/docs/hooks-intro.html), meaning it cannot be used with classes. You can either use [withRouter](#withRouter) or wrap your class in a function component.
-### router object
+## `router` object
The following is the definition of the `router` object returned by both [`useRouter`](#useRouter) and [`withRouter`](#withRouter):
@@ -45,27 +45,9 @@ The following is the definition of the `router` object returned by both [`useRou
- `query`: `Object` - The query string parsed to an object. It will be an empty object during prerendering if the page doesn't have [data fetching requirements](/docs/basic-features/data-fetching.md). Defaults to `{}`
- `asPath`: `String` - Actual path (including the query) shown in the browser
-Additionally, the [`Router API`](#router-api) is also included inside the object.
+Additionally, the following methods are also included inside `router`:
-## withRouter
-
-If [`useRouter`](#useRouter) is not the best fit for you, `withRouter` can also add the same [`router` object](#router-object) to any component, here's how to use it:
-
-```jsx
-import { withRouter } from 'next/router'
-
-function Page({ router }) {
- return
{router.pathname}
-}
-
-export default withRouter(Page)
-```
-
-## Router API
-
-The API of `Router`, exported by `next/router`, is defined below.
-
-### Router.push
+### router.push
Examples
@@ -77,9 +59,7 @@ The API of `Router`, exported by `next/router`, is defined below.
Handles client-side transitions, this method is useful for cases where [`next/link`](/docs/api-reference/next/link.md) is not enough.
```jsx
-import Router from 'next/router'
-
-Router.push(url, as, options)
+router.push(url, as, options)
```
- `url` - The URL to navigate to. This is usually the name of a `page`
@@ -87,81 +67,118 @@ Router.push(url, as, options)
- `options` - Optional object with the following configuration options:
- [`shallow`](/docs/routing/shallow-routing.md): Update the path of the current page without rerunning [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation), [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering) or [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md). Defaults to `false`
-> You don't need to use `Router` for external URLs, [window.location](https://developer.mozilla.org/en-US/docs/Web/API/Window/location) is better suited for those cases.
+> You don't need to use `router.push` for external URLs. [window.location](https://developer.mozilla.org/en-US/docs/Web/API/Window/location) is better suited for those cases.
#### Usage
Navigating to `pages/about.js`, which is a predefined route:
```jsx
-import Router from 'next/router'
+import { useRouter } from 'next/router'
+
+export default function Page() {
+ const router = useRouter()
-function Page() {
- return Router.push('/about')}>Click me
+ return router.push('/about')}>Click me
}
```
Navigating `pages/post/[pid].js`, which is a dynamic route:
```jsx
-import Router from 'next/router'
+import { useRouter } from 'next/router'
+
+export default function Page() {
+ const router = useRouter()
-function Page() {
return (
- Router.push('/post/[pid]', '/post/abc')}>
+ router.push('/post/[pid]', '/post/abc')}>
Click me
)
}
```
+Redirecting the user to `pages/login.js`, useful for pages behind authentication:
+
+```jsx
+import { useEffect } from 'react'
+import { useRouter } from 'next/router'
+
+// Here you would fetch and return the user
+const useUser = () => ({ user: null, loading: false })
+
+export default function Page() {
+ const { user, loading } = useUser()
+ const router = useRouter()
+
+ useEffect(() => {
+ if (!(user || loading)) {
+ router.push('/login')
+ }
+ }, [user, loading])
+
+ return Redirecting...
+}
+```
+
#### With URL object
You can use an URL object in the same way you can use it for [`next/link`](/docs/api-reference/next/link.md#with-url-object). Works for both the `url` and `as` parameters:
```jsx
-import Router from 'next/router'
+import { useRouter } from 'next/router'
-const handler = () => {
- Router.push({
- pathname: '/about',
- query: { name: 'Vercel' },
- })
-}
+export default function ReadMore() {
+ const router = useRouter()
-function ReadMore() {
return (
-
- Click here to read more
-
+ {
+ router.push({
+ pathname: '/about',
+ query: { name: 'Vercel' },
+ })
+ }}
+ >
+ Click here to read more
+
)
}
+```
+
+### router.replace
-export default ReadMore
+Similar to the `replace` prop in [`next/link`](/docs/api-reference/next/link.md), `router.replace` will prevent adding a new URL entry into the `history` stack.
+
+```jsx
+router.replace(url, as, options)
```
-### Router.replace
+- The API for `router.replace` is exactly the same as the API for [`router.push`](#router.push).
+
+#### Usage
-Similar to the `replace` prop in [`next/link`](/docs/api-reference/next/link.md), `Router.replace` will prevent adding a new URL entry into the `history` stack, take a look at the following example:
+Take a look at the following example:
```jsx
-import Router from 'next/router'
+import { useRouter } from 'next/router'
-Router.replace('/home')
-```
+export default function Page() {
+ const router = useRouter()
-The API for `Router.replace` is exactly the same as that used for [`Router.push`](#router.push).
+ return router.replace('/home')}>Click me
+}
+```
-### Router.prefetch
+### router.prefetch
Prefetch pages for faster client-side transitions. This method is only useful for navigations without [`next/link`](/docs/api-reference/next/link.md), as `next/link` takes care of prefetching pages automatically.
> This is a production only feature. Next.js doesn't prefetch pages on development.
```jsx
-import Router from 'next/router'
-
-Router.prefetch(url, as)
+router.prefetch(url, as)
```
- `url` - The path to a `page` inside the `pages` directory
@@ -173,9 +190,10 @@ Let's say you have a login page, and after a login, you redirect the user to the
```jsx
import { useCallback, useEffect } from 'react'
-import Router from 'next/router'
+import { useRouter } from 'next/router'
export default function Login() {
+ const router = useRouter()
const handleSubmit = useCallback((e) => {
e.preventDefault()
@@ -187,13 +205,13 @@ export default function Login() {
}),
}).then((res) => {
// Do a fast client-side transition to the already prefetched dashboard page
- if (res.ok) Router.push('/dashboard')
+ if (res.ok) router.push('/dashboard')
})
}, [])
useEffect(() => {
// Prefetch the dashboard page as the user will go there after the login
- Router.prefetch('/dashboard')
+ router.prefetch('/dashboard')
}, [])
return (
@@ -205,57 +223,82 @@ export default function Login() {
}
```
-### Router.beforePopState
+### router.beforePopState
In some cases (for example, if using a [Custom Server](/docs/advanced-features/custom-server.md)), you may wish to listen to [popstate](https://developer.mozilla.org/en-US/docs/Web/Events/popstate) and do something before the router acts on it.
-You could use this to manipulate the request, or force a SSR refresh, as in the following example:
-
```jsx
-import Router from 'next/router'
-
-Router.beforePopState(({ url, as, options }) => {
- // I only want to allow these two routes!
- if (as !== '/' && as !== '/other') {
- // Have SSR render bad routes as a 404.
- window.location.href = as
- return false
- }
-
- return true
-})
+router.beforePopState(cb)
```
-`Router.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 browser
- - `options`: `Object` - Additional options sent by [Router.push](#router.push)
+ - `options`: `Object` - Additional options sent by [router.push](#router.push)
-If 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](/docs/advanced-features/custom-server.md#disabling-file-system-routing).
+If `cb` returns `false`, the Next.js router will not handle `popstate`, and you'll be responsible for handling it in that case. See [Disabling file-system routing](/docs/advanced-features/custom-server.md#disabling-file-system-routing).
-### Router.back
+#### Usage
+
+You could use `beforePopState` to manipulate the request, or force a SSR refresh, as in the following example:
+
+```jsx
+import { useEffect } from 'react'
+import { useRouter } from 'next/router'
+
+export default function Page() {
+ const router = useRouter()
+
+ useEffect(() => {
+ router.beforePopState(({ url, as, options }) => {
+ // I only want to allow these two routes!
+ if (as !== '/' && as !== '/other') {
+ // Have SSR render bad routes as a 404.
+ window.location.href = as
+ return false
+ }
+
+ return true
+ })
+ }, [])
+
+ return Welcome to the page
+}
+```
+
+### router.back
Navigate back in history. Equivalent to clicking the browser’s back button. It executes `window.history.back()`.
+#### Usage
+
```jsx
-import Router from 'next/router'
+import { useRouter } from 'next/router'
-Router.back()
+export default function Page() {
+ const router = useRouter()
+
+ return router.back()}>Click here to go back
+}
```
-### Router.reload
+### router.reload
Reload the current URL. Equivalent to clicking the browser’s refresh button. It executes `window.location.reload()`.
+#### Usage
+
```jsx
-import Router from 'next/router'
+import { useRouter } from 'next/router'
+
+export default function Page() {
+ const router = useRouter()
-Router.reload()
+ return router.reload()}>Click here to reload
+}
```
-### Router.events
+### router.events
Examples
@@ -264,7 +307,7 @@ Router.reload()
-You can listen to different events happening inside the Router. Here's a list of supported events:
+You can listen to different events happening inside the Next.js Router. Here's a list of supported events:
- `routeChangeStart(url)` - Fires when a route starts to change
- `routeChangeComplete(url)` - Fires when a route changed completely
@@ -274,53 +317,82 @@ You can listen to different events happening inside the Router. Here's a list of
- `hashChangeStart(url)` - Fires when the hash will change but not the page
- `hashChangeComplete(url)` - Fires when the hash has changed but not the page
-> Here `url` is the URL shown in the browser. If you call `Router.push(url, as)` (or similar), then the value of `url` will be `as`.
+> Here `url` is the URL shown in the browser. If you call `router.push(url, as)` (or similar), then the value of `url` will be `as`.
+
+#### Usage
-For example, to listen to the router event `routeChangeStart`, do the following:
+For example, to listen to the router event `routeChangeStart`, open or create `pages/_app.js` and subscribe to the event, like so:
```jsx
-import Router from 'next/router'
+import { useEffect } from 'react'
+import { useRouter } from 'next/router'
-const handleRouteChange = (url) => {
- console.log('App is changing to: ', url)
-}
+export default function MyApp({ Component, pageProps }) {
+ const router = useRouter()
-Router.events.on('routeChangeStart', handleRouteChange)
-```
+ useEffect(() => {
+ const handleRouteChange = (url) => {
+ console.log('App is changing to: ', url)
+ }
-If you no longer want to listen to the event, unsubscribe with the `off` method:
+ router.events.on('routeChangeStart', handleRouteChange)
-```jsx
-import Router from 'next/router'
+ // If the component is unmounted, unsubscribe
+ // from the event with the `off` method:
+ return () => {
+ router.events.off('routeChangeStart', handleRouteChange)
+ }
+ }, [])
-Router.events.off('routeChangeStart', handleRouteChange)
+ return
+}
```
+> We use a [Custom App](/docs/advanced-features/custom-app.md) (`pages/_app.js`) for this example to subscribe to the event because it's not unmounted on page navigations, but you can subscribe to router events on any component in your application.
+
+Router events should be registered when a component mounts ([useEffect](https://reactjs.org/docs/hooks-effect.html) or [componentDidMount](https://reactjs.org/docs/react-component.html#componentdidmount) / [componentWillUnmount](https://reactjs.org/docs/react-component.html#componentwillunmount)) or imperatively when an event happens.
+
If 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:
```jsx
-import Router from 'next/router'
+import { useEffect } from 'react'
+import { useRouter } from 'next/router'
-Router.events.on('routeChangeError', (err, url) => {
- if (err.cancelled) {
- console.log(`Route to ${url} was cancelled!`)
- }
-})
+export default function MyApp({ Component, pageProps }) {
+ const router = useRouter()
+
+ useEffect(() => {
+ const handleRouteChangeError = (err, url) => {
+ if (err.cancelled) {
+ console.log(`Route to ${url} was cancelled!`)
+ }
+ }
+
+ router.events.on('routeChangeError', handleRouteChangeError)
+
+ // If the component is unmounted, unsubscribe
+ // from the event with the `off` method:
+ return () => {
+ router.events.off('routeChangeError', handleRouteChangeError)
+ }
+ }, [])
+
+ return
+}
```
-Router events should be registered when a component mounts ([useEffect](https://reactjs.org/docs/hooks-effect.html) or [componentDidMount](https://reactjs.org/docs/react-component.html#componentdidmount) / [componentWillUnmount](https://reactjs.org/docs/react-component.html#componentwillunmount)) or imperatively when an event happens, as in the following example:
+## withRouter
+
+If [`useRouter`](#useRouter) is not the best fit for you, `withRouter` can also add the same [`router` object](#router-object) to any component.
+
+### Usage
```jsx
-import Router from 'next/router'
+import { withRouter } from 'next/router'
-useEffect(() => {
- const handleRouteChange = (url) => {
- console.log('App is changing to: ', url)
- }
+function Page({ router }) {
+ return {router.pathname}
+}
- Router.events.on('routeChangeStart', handleRouteChange)
- return () => {
- Router.events.off('routeChangeStart', handleRouteChange)
- }
-}, [])
+export default withRouter(Page)
```
diff --git a/docs/routing/imperatively.md b/docs/routing/imperatively.md
index ba4659d889f28..7dbbf7a16a42d 100644
--- a/docs/routing/imperatively.md
+++ b/docs/routing/imperatively.md
@@ -1,5 +1,5 @@
---
-description: Client-side navigations are also possible using the Router API instead of the Link component. Learn more here.
+description: Client-side navigations are also possible using the Next.js Router instead of the Link component. Learn more here.
---
# Imperatively
@@ -11,18 +11,18 @@ description: Client-side navigations are also possible using the Router API inst
-[`next/link`](/docs/api-reference/next/link.md) should be able to cover most of your routing needs, but you can also do client-side navigations without it, take a look at the [Router API documentation](/docs/api-reference/next/router.md#router-api).
+[`next/link`](/docs/api-reference/next/link.md) should be able to cover most of your routing needs, but you can also do client-side navigations without it, take a look at the [documentation for `next/router`](/docs/api-reference/next/router.md).
-The following example shows the basic usage of the Router API:
+The following example shows how to do basic page navigations with [`useRouter`](/docs/api-reference/next/router.md#useRouter):
```jsx
-import Router from 'next/router'
+import { useRouter } from 'next/router'
function ReadMore() {
+ const router = useRouter()
+
return (
-
- Click Router.push('/about')}>here to read more
-
+ router.push('/about')}>Click here to read more
)
}
diff --git a/docs/routing/shallow-routing.md b/docs/routing/shallow-routing.md
index 9aa21feae566b..caa9cf35138e1 100644
--- a/docs/routing/shallow-routing.md
+++ b/docs/routing/shallow-routing.md
@@ -38,14 +38,6 @@ function Page() {
export default Page
```
-If you don't need to add the router object to the page, you can also use the [Router API](/docs/api-reference/next/router.md#router-api) directly, like so:
-
-```jsx
-import Router from 'next/router'
-// Inside your page
-Router.push('/?counter=10', undefined, { 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`](https://reactjs.org/docs/react-component.html#componentdidupdate) as shown below:
@@ -65,7 +57,7 @@ componentDidUpdate(prevProps) {
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:
```jsx
-Router.push('/?counter=10', '/about?counter=10', { shallow: true })
+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.