redirect
redirect
関数を使用すると、ユーザーを別のURLにリダイレクトできます。redirect
はサーバーコンポーネント、ルートハンドラー、サーバーアクションで使用可能です。
ストリーミングコンテキストで使用すると、クライアントサイドでリダイレクトを実行するためのmetaタグが挿入されます。サーバーアクションで使用すると、呼び出し元に303 HTTPリダイレクトレスポンスが返されます。それ以外の場合、307 HTTPリダイレクトレスポンスが返されます。
リソースが存在しない場合は、代わりにnotFound
関数を使用できます。
リファレンス
パラメータ
redirect
関数は2つの引数を受け取ります:
redirect(path, type)
パラメータ | タイプ | 説明 |
---|---|---|
path | string | リダイレクト先のURL。相対パスまたは絶対パスを指定可能。 |
type | 'replace' (デフォルト)または 'push' (サーバーアクションではデフォルト) | 実行するリダイレクトのタイプ。 |
デフォルトでは、redirect
はサーバーアクションではpush
(ブラウザの履歴スタックに新しいエントリを追加)、それ以外の場所ではreplace
(ブラウザの履歴スタックで現在のURLを置換)を使用します。type
パラメータを指定することでこの動作を上書きできます。
type
パラメータはサーバーコンポーネントでは効果がありません。
戻り値
redirect
は値を返しません。
動作
- サーバーアクションとルートハンドラーでは、
redirect
はtry/catch
ブロックの後に呼び出す必要があります。 - 307(一時的)ではなく308(永続的)HTTPリダイレクトを返したい場合は、代わりに
permanentRedirect
関数を使用できます。 redirect
は内部的にエラーをスローするため、try/catch
ブロックの外で呼び出す必要があります。redirect
はレンダリングプロセス中にクライアントコンポーネントで呼び出せますが、イベントハンドラーでは呼び出せません。代わりにuseRouter
フックを使用できます。redirect
は絶対URLも受け入れ、外部リンクへのリダイレクトに使用できます。- レンダリングプロセスの前にリダイレクトしたい場合は、
next.config.js
またはミドルウェアを使用してください。
例
サーバーコンポーネント
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
はTypeScriptのnever
型を使用しているため、return redirect()
と書く必要はありません。
クライアントコンポーネント
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>
}
豆知識: サーバーサイドレンダリング (SSR) 中の初期ページロード時にクライアントコンポーネントで
redirect
を使用すると、サーバーサイドリダイレクトが実行されます。
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
が使用されていましたが、多くのブラウザは302
を使用する際に、元のリクエストメソッドに関係なく、リダイレクトのリクエストメソッドをPOST
からGET
に変更していました。
/users
から/people
へのリダイレクトの例を考えてみましょう。新しいユーザーを作成するために/users
にPOST
リクエストを送信し、302
一時リダイレクトに従う場合、リクエストメソッドはPOST
からGET
に変更されます。これは理にかなっていません。新しいユーザーを作成するには、GET
リクエストではなくPOST
リクエストを/people
に送信する必要があります。
307
ステータスコードの導入により、リクエストメソッドがPOST
として保持されるようになりました。
302
- 一時リダイレクト、リクエストメソッドをPOST
からGET
に変更307
- 一時リダイレクト、リクエストメソッドをPOST
として保持
redirect()
メソッドはデフォルトで302
ではなく307
を使用するため、リクエストは常にPOST
リクエストとして保持されます。
HTTPリダイレクトについてさらに学ぶ。
バージョン履歴
バージョン | 変更点 |
---|---|
v13.0.0 | redirect が導入されました。 |