redirect
redirect 関数は、ユーザーを別のURLにリダイレクトするためのものです。redirect はServer Components、Route Handlers、およびServer Actionsで使用できます。
ストリーミングコンテキストで使用される場合、クライアント側でリダイレクトを発生させるためのmetaタグを挿入します。server actionで使用される場合、呼び出し元に303 HTTPリダイレクトレスポンスを返します。それ以外の場合は、呼び出し元に307 HTTPリダイレクトレスポンスを返します。
リソースが存在しない場合は、代わりにnotFound 関数を使用できます。
Good to know:
- Server ActionsとRoute Handlersでは、
redirectはtry/catchブロックの後に呼び出す必要があります。- 307(Temporary)ではなく308(Permanent)のHTTPリダイレクトを返したい場合は、代わりに
permanentRedirect関数を使用できます。
パラメータ
redirect 関数は2つの引数を受け取ります:
redirect(path, type)
| パラメータ | 型 | 説明 |
|---|---|---|
path | string | リダイレクト先のURL。相対パスまたは絶対パスを指定できます。 |
type | 'replace'(デフォルト)または 'push'(Server Actionsのデフォルト) | 実行するリダイレクトのタイプ。 |
デフォルトでは、redirect はServer Actionsではpush(ブラウザの履歴スタックに新しいエントリを追加)を使用し、それ以外の場所ではreplace(ブラウザの履歴スタックの現在のURLを置き換え)を使用します。この動作は、type パラメータを指定することで上書きできます。
type パラメータは、Server Componentsで使用される場合には効果がありません。
戻り値
redirect は値を返しません。
例
Server Component
redirect() 関数を呼び出すと、NEXT_REDIRECT エラーがスローされ、それがスローされたルートセグメントのレンダリングが終了します。
- TypeScript
- JavaScript
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')
}
// ...
}
Good to know:
redirectはreturn redirect()を使用する必要はありません。これはTypeScriptのnever型を使用しているためです。
Client Component
redirect はClient Componentで直接使用できます。
- TypeScript
- JavaScript
'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>
}
Good to know: Client Componentで
redirectを使用する際、Server-Side Rendering(SSR)中の初期ページロード時にはサーバーサイドリダイレクトが行われます。
redirect はServer Actionを通じてClient Componentで使用できます。ユーザーをリダイレクトするためにイベントハンドラを使用する必要がある場合は、useRouterフックを使用できます。
- TypeScript
- JavaScript
'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>
)
}
- TypeScript
- JavaScript
'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')}`)
}
FAQ
なぜredirectは307と308を使用するのですか?
redirect()を使用すると、ステータスコードとして307(一時的なリダイレクト)と308(恒久的なリダイレクト)が使用されていることに気付くかもしれません。従来は、一時的なリダイレクトには302、恒久的なリダイレクトには301が使用されていましたが、多くのブラウザは302を使用する際にリダイレクトのリクエストメソッドをPOSTからGETに変更しました。これは、元のリクエストメソッドに関係なく行われます。
例えば、/usersから/peopleへのリダイレクトの例を考えてみましょう。新しいユーザーを作成するために/usersにPOSTリクエストを送信し、302一時的なリダイレクトに従うと、リクエストメソッドはPOSTからGETに変更されます。これは、新しいユーザーを作成するためには/peopleにPOSTリクエストを送信する必要があるため、理にかなっていません。
307ステータスコードの導入により、リクエストメソッドはPOSTのまま保持されます。
302- 一時的なリダイレクトで、リクエストメソッドをPOSTからGETに変更します307- 一時的なリダイレクトで、リクエストメソッドをPOSTのまま保持します
redirect()メソッドはデフォルトで307を使用し、302一時的なリダイレクトの代わりに使用するため、リクエストは常にPOSTリクエストとして保持されます。
バージョン履歴
| バージョン | 変更内容 |
|---|---|
v13.0.0 | redirect が導入されました。 |