redirect
Функция redirect
позволяет перенаправлять пользователя на другой URL. redirect
может использоваться в Серверных компонентах (Server Components), Обработчиках маршрутов (Route Handlers) и Серверных действиях (Server Actions).
При использовании в контексте потоковой передачи (streaming context) функция вставляет мета-тег для выполнения перенаправления на стороне клиента. При использовании в серверном действии она возвращает HTTP-ответ с кодом 303 для перенаправления вызывающей стороне. В остальных случаях возвращается HTTP-ответ с кодом 307.
Если ресурс не существует, вместо этого можно использовать функцию notFound
.
Справочник
Параметры
Функция redirect
принимает два аргумента:
redirect(path, type)
Параметр | Тип | Описание |
---|---|---|
path | string | URL для перенаправления. Может быть относительным или абсолютным. |
type | 'replace' (по умолчанию) или 'push' (по умолчанию в Server Actions) | Тип перенаправления. |
По умолчанию redirect
использует push
(добавляет новую запись в стек истории браузера) в Серверных действиях (Server Actions) и replace
(заменяет текущий URL в стеке истории браузера) во всех остальных случаях. Это поведение можно переопределить, указав параметр type
.
Параметр type
не имеет эффекта при использовании в Серверных компонентах.
Возвращаемое значение
Функция redirect
не возвращает значения.
Поведение
- В Серверных действиях и Обработчиках маршрутов
redirect
должна вызываться после блокаtry/catch
. - Если требуется вернуть HTTP-перенаправление с кодом 308 (Постоянное) вместо 307 (Временное), можно использовать функцию
permanentRedirect
. redirect
внутренне генерирует ошибку, поэтому должна вызываться вне блоковtry/catch
.redirect
может вызываться в Клиентских компонентах во время процесса рендеринга, но не в обработчиках событий. Вместо этого можно использовать хукuseRouter
.redirect
также принимает абсолютные URL и может использоваться для перенаправления на внешние ссылки.- Если требуется выполнить перенаправление до процесса рендеринга, используйте
next.config.js
или Middleware.
Примеры
Серверный компонент
Вызов функции redirect()
генерирует ошибку NEXT_REDIRECT
и прерывает рендеринг сегмента маршрута, в котором она была вызвана.
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')
}
// ...
}
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')
}
// ...
}
Важно:
redirect
не требует использованияreturn redirect()
, так как использует тип TypeScriptnever
.
Клиентский компонент
redirect
может использоваться напрямую в Клиентском компоненте.
'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>
}
'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>
}
Важно: При использовании
redirect
в Клиентском компоненте во время первоначальной загрузки страницы при SSR выполняется серверное перенаправление.
redirect
может использоваться в Клиентском компоненте через Серверное действие. Если требуется использовать обработчик событий для перенаправления пользователя, можно использовать хук useRouter
.
'use client'
import { navigate } from './actions'
export function ClientRedirect() {
return (
<form action={navigate}>
<input type="text" name="id" />
<button>Submit</button>
</form>
)
}
'use client'
import { navigate } from './actions'
export function ClientRedirect() {
return (
<form action={navigate}>
<input type="text" name="id" />
<button>Submit</button>
</form>
)
}
'use server'
import { redirect } from 'next/navigation'
export async function navigate(data: FormData) {
redirect(`/posts/${data.get('id')}`)
}
'use server'
import { redirect } from 'next/navigation'
export async function navigate(data) {
redirect(`/posts/${data.get('id')}`)
}
Часто задаваемые вопросы
Почему redirect
использует коды 307 и 308?
При использовании redirect()
можно заметить, что используются коды состояния 307
для временного перенаправления и 308
для постоянного. Хотя традиционно 302
использовался для временного перенаправления, а 301
для постоянного, многие браузеры изменяли метод запроса при перенаправлении с POST
на GET
при использовании 302
, независимо от исходного метода запроса.
Рассмотрим пример перенаправления с /users
на /people
. Если сделать POST
запрос на /users
для создания нового пользователя и получить 302
временное перенаправление, метод запроса изменится с POST
на GET
. Это нелогично, так как для создания пользователя должен использоваться POST
запрос на /people
, а не GET
.
Введение кода состояния 307
означает, что метод запроса сохраняется как POST
.
302
- Временное перенаправление, изменяет метод запроса сPOST
наGET
307
- Временное перенаправление, сохраняет метод запроса какPOST
Метод redirect()
по умолчанию использует 307
вместо 302
, что означает сохранение POST
запросов.
Подробнее о HTTP-перенаправлениях.
История версий
Версия | Изменения |
---|---|
v13.0.0 | Добавлена функция redirect . |