redirect
redirect 関数を使用すると、ユーザーを別の URL にリダイレクトできます。redirect は、サーバーコンポーネントおよびクライアントコンポーネント、ルートハンドラー、およびサーバーアクションでのレンダリング中に使用できます。
ストリーミングコンテキストで使用される場合、クライアント側でリダイレクトをエミットするためのメタタグが挿入されます。サーバーアクションで使用される場合、呼び出し元に 303 HTTP リダイレクト応答が返されます。それ以外の場合は、呼び出し元に 307 HTTP リダイレクト応答が返されます。
リソースが存在しない場合は、代わりにnotFound 関数を使用できます。
リファレンス
Parameters
redirect 関数は 2 つの引数を受け取ります
redirect(path, type)| パラメータ | タイプ | 説明 |
|---|---|---|
path | string | リダイレクト先の URL。相対パスまたは絶対パスを指定できます。 |
type | 'replace' (デフォルト) または 'push' (サーバーアクションではデフォルト) | 実行するリダイレクトのタイプ。 |
デフォルトでは、redirect はサーバーアクションでは push (ブラウザの履歴スタックに新しいエントリを追加) を使用し、それ以外の場所では replace (ブラウザの履歴スタックで現在の URL を置き換える) を使用します。type パラメータを指定することで、この動作を上書きできます。
RedirectType オブジェクトには、type パラメータに使用できるオプションが含まれています。
import { redirect, RedirectType } from 'next/navigation'
redirect('/redirect-to', RedirectType.replace)
// or
redirect('/redirect-to', RedirectType.push)type パラメータは、サーバーコンポーネントで使用される場合には効果がありません。
戻り値
redirect は値を返しません。
動作
- サーバーアクションおよびルートハンドラーでは、
try/catchステートメントを使用する場合、リダイレクトはtryブロックの外側で呼び出す必要があります。 - 一時的なリダイレクト (307) ではなく、永続的なリダイレクト (308) を返すことを優先する場合は、代わりに
permanentRedirect関数を使用できます。 redirectはエラーをスローするため、try/catchステートメントを使用する場合はtryブロックの外側で呼び出す必要があります。redirectはクライアントコンポーネントのレンダリング中に呼び出すことができますが、イベントハンドラーでは呼び出せません。代わりにuseRouterフックを使用できます。redirectは絶対 URL も受け入れ、外部リンクへのリダイレクトに使用できます。- レンダリングプロセス前にリダイレクトしたい場合は、
next.config.jsまたはProxy を使用してください。
例
サーバーコンポーネント
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')
}
// ...
}知っておくと良いこと:
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>
}知っておくと良いこと: サーバーサイドレンダリング (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 server'
import { redirect } from 'next/navigation'
export async function navigate(data: FormData) {
redirect(`/posts/${data.get('id')}`)
}FAQ
redirect が 307 および 308 を使用する理由
redirect() を使用すると、一時的なリダイレクトには 307、永続的なリダイレクトには 308 のステータスコードが使用されることに気づくかもしれません。従来、一時的なリダイレクトには 302、永続的なリダイレクトには 301 が使用されていましたが、多くのブラウザでは 302 を使用した場合、元のリクエストメソッドに関係なく、リダイレクトのリクエストメソッドを POST から GET に変更していました。
/users から /people へのリダイレクトを例にとると、新しいユーザーを作成するために POST リクエストを /users に送信し、302 の一時的なリダイレクトに従う場合、リクエストメソッドは POST から GET に変更されます。これは、新しいユーザーを作成するには /people に POST リクエストを送信する必要があり、GET リクエストではないため、理にかなっていません。
307 ステータスコードの導入により、リクエストメソッドが POST のまま維持されるようになります。
302- 一時的なリダイレクト、リクエストメソッドをPOSTからGETに変更します307- 一時的なリダイレクト、リクエストメソッドをPOSTのまま維持します
redirect() メソッドは、デフォルトで 302 の一時的なリダイレクトの代わりに 307 を使用するため、リクエストは常に POST リクエストとして維持されます。
HTTP リダイレクトについてさらに詳しく。
バージョン履歴
| バージョン | 変更履歴 |
|---|---|
v13.0.0 | redirect が導入されました。 |
役に立ちましたか?