UNPKG

next

Version:

The React Framework

223 lines (155 loc) • 7.93 kB
--- title: redirect description: API Reference for the redirect function. related: links: - app/api-reference/functions/permanentRedirect --- The `redirect` function allows you to redirect the user to another URL. `redirect` can be used while rendering in [Server and Client Components](/docs/app/getting-started/server-and-client-components), [Route Handlers](/docs/app/api-reference/file-conventions/route), and [Server Functions](/docs/app/getting-started/mutating-data). When used in a [streaming context](/docs/app/getting-started/linking-and-navigating#streaming), this will insert a meta tag to emit the redirect on the client side. When used in a server action, it will serve a 303 HTTP redirect response to the caller. Otherwise, it will serve a 307 HTTP redirect response to the caller. If a resource doesn't exist, you can use the [`notFound` function](/docs/app/api-reference/functions/not-found) instead. ## Reference ### Parameters The `redirect` function accepts two arguments: ```js redirect(path, type) ``` | Parameter | Type | Description | | --------- | ------------------------------------------------------------- | ----------------------------------------------------------- | | `path` | `string` | The URL to redirect to. Can be a relative or absolute path. | | `type` | `'replace'` (default) or `'push'` (default in Server Actions) | The type of redirect to perform. | By default, `redirect` will use `push` (adding a new entry to the browser history stack) in [Server Actions](/docs/app/getting-started/mutating-data) and `replace` (replacing the current URL in the browser history stack) everywhere else. You can override this behavior by specifying the `type` parameter. The `RedirectType` object contains the available options for the `type` parameter. ```ts import { redirect, RedirectType } from 'next/navigation' redirect('/redirect-to', RedirectType.replace) // or redirect('/redirect-to', RedirectType.push) ``` The `type` parameter has no effect when used in Server Components. ### Returns `redirect` does not return a value. ## Behavior - In Server Actions and Route Handlers, redirect should be called **outside** the `try` block when using `try/catch` statements. - If you prefer to return a 308 (Permanent) HTTP redirect instead of 307 (Temporary), you can use the [`permanentRedirect` function](/docs/app/api-reference/functions/permanentRedirect) instead. - `redirect` throws an error so it should be called **outside** the `try` block when using `try/catch` statements. - `redirect` can be called in Client Components during the rendering process but not in event handlers. You can use the [`useRouter` hook](/docs/app/api-reference/functions/use-router) instead. - `redirect` also accepts absolute URLs and can be used to redirect to external links. - If you'd like to redirect before the render process, use [`next.config.js`](/docs/app/guides/redirecting#redirects-in-nextconfigjs) or [Proxy](/docs/app/guides/redirecting#nextresponseredirect-in-proxy). ## Example ### Server Component Invoking the `redirect()` function throws a `NEXT_REDIRECT` error and terminates rendering of the route segment in which it was thrown. ```tsx filename="app/team/[id]/page.tsx" switcher import { redirect } from 'next/navigation' async function fetchTeam(id: string) { const res = await fetch('https://...') if (!res.ok) return undefined return res.json() } export default async function Profile({ params, }: { params: Promise<{ id: string }> }) { const { id } = await params const team = await fetchTeam(id) if (!team) { redirect('/login') } // ... } ``` ```jsx filename="app/team/[id]/page.js" switcher import { redirect } from 'next/navigation' async function fetchTeam(id) { const res = await fetch('https://...') if (!res.ok) return undefined return res.json() } export default async function Profile({ params }) { const { id } = await params const team = await fetchTeam(id) if (!team) { redirect('/login') } // ... } ``` > **Good to know**: `redirect` does not require you to use `return redirect()` as it uses the TypeScript [`never`](https://www.typescriptlang.org/docs/handbook/2/functions.html#never) type. ### Client Component `redirect` can be directly used in a Client Component. ```tsx filename="components/client-redirect.tsx" switcher 'use client' import { redirect, usePathname } from 'next/navigation' export function ClientRedirect() { const pathname = usePathname() if (pathname.startsWith('/admin') && !pathname.includes('/login')) { redirect('/admin/login') } return <div>Login Page</div> } ``` ```jsx filename="components/client-redirect.jsx" switcher 'use client' import { redirect, usePathname } from 'next/navigation' export function ClientRedirect() { const pathname = usePathname() if (pathname.startsWith('/admin') && !pathname.includes('/login')) { redirect('/admin/login') } return <div>Login Page</div> } ``` > **Good to know**: When using `redirect` in a Client Component on initial page load during Server-Side Rendering (SSR), it will perform a server-side redirect. `redirect` can be used in a Client Component through a Server Action. If you need to use an event handler to redirect the user, you can use the [`useRouter`](/docs/app/api-reference/functions/use-router) hook. ```tsx filename="app/client-redirect.tsx" switcher 'use client' import { navigate } from './actions' export function ClientRedirect() { return ( <form action={navigate}> <input type="text" name="id" /> <button>Submit</button> </form> ) } ``` ```jsx filename="app/client-redirect.jsx" switcher 'use client' import { navigate } from './actions' export function ClientRedirect() { return ( <form action={navigate}> <input type="text" name="id" /> <button>Submit</button> </form> ) } ``` ```ts filename="app/actions.ts" switcher 'use server' import { redirect } from 'next/navigation' export async function navigate(data: FormData) { redirect(`/posts/${data.get('id')}`) } ``` ```js filename="app/actions.js" switcher 'use server' import { redirect } from 'next/navigation' export async function navigate(data) { redirect(`/posts/${data.get('id')}`) } ``` ## FAQ ### Why does `redirect` use 307 and 308? When using `redirect()` you may notice that the status codes used are `307` for a temporary redirect, and `308` for a permanent redirect. While traditionally a `302` was used for a temporary redirect, and a `301` for a permanent redirect, many browsers changed the request method of the redirect, from a `POST` to `GET` request when using a `302`, regardless of the origins request method. Taking the following example of a redirect from `/users` to `/people`, if you make a `POST` request to `/users` to create a new user, and are conforming to a `302` temporary redirect, the request method will be changed from a `POST` to a `GET` request. This doesn't make sense, as to create a new user, you should be making a `POST` request to `/people`, and not a `GET` request. The introduction of the `307` status code means that the request method is preserved as `POST`. - `302` - Temporary redirect, will change the request method from `POST` to `GET` - `307` - Temporary redirect, will preserve the request method as `POST` The `redirect()` method uses a `307` by default, instead of a `302` temporary redirect, meaning your requests will _always_ be preserved as `POST` requests. [Learn more](https://developer.mozilla.org/docs/Web/HTTP/Redirections) about HTTP Redirects. ## Version History | Version | Changes | | --------- | ---------------------- | | `v13.0.0` | `redirect` introduced. |