Menu

redirect

redirect関数は、ユーザーを別のURLにリダイレクトすることができます。redirectサーバーコンポーネントルートハンドラー、およびサーバーアクションで使用できます。

ストリーミングコンテキストで使用する場合、クライアント側でリダイレクトを実行するためのmetaタグが挿入されます。サーバーアクションで使用する場合は、呼び出し元に303 HTTPリダイレクトレスポンスを返します。それ以外の場合は、307 HTTPリダイレクトレスポンスを返します。

リソースが存在しない場合は、代わりにnotFound関数を使用できます。

補足:

  • サーバーアクションとルートハンドラーでは、redirecttry/catchブロックの後に呼び出す必要があります。
  • 307(一時的)HTTPリダイレクトの代わりに308(恒久的)HTTPリダイレクトを返す場合は、代わりにpermanentRedirect関数を使用できます。

パラメータ

redirect関数は2つの引数を受け取ります:

redirect(path, type)
パラメータ説明
pathstringリダイレクト先のURL。相対パスまたは絶対パスが指定可能。
type'replace'(デフォルト)または'push'(サーバーアクションではデフォルト)実行するリダイレクトの種類。

デフォルトでは、redirectサーバーアクションではpush(ブラウザの履歴スタックに新しいエントリを追加)を使用し、その他の場所ではreplace(ブラウザの履歴スタック内の現在のURLを置き換え)を使用します。typeパラメータを指定することで、この動作をオーバーライドすることができます。

typeパラメータはサーバーコンポーネントで使用する場合、効果はありません。

戻り値

redirectは値を返しません。

サーバーコンポーネント

redirect()関数を呼び出すと、NEXT_REDIRECTエラーがスローされ、それが発生したルートセグメントのレンダリングが終了します。

app/team/[id]/page.tsx
TypeScript
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はクライアントコンポーネントで直接使用できます。

components/client-redirect.tsx
TypeScript
'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フックを使用できます。

app/client-redirect.tsx
TypeScript
'use client'
 
import { navigate } from './actions'
 
export function ClientRedirect() {
  return (
    <form action={navigate}>
      <input type="text" name="id" />
      <button>Submit</button>
    </form>
  )
}
app/actions.ts
TypeScript
'use server'
 
import { redirect } from 'next/navigation'
 
export async function navigate(data: FormData) {
  redirect(`/posts/${data.get('id')}`)
}

よくある質問

なぜredirectは307と308を使用するのですか?

redirect()を使用すると、一時的なリダイレクトには307、恒久的なリダイレクトには308のステータスコードが使用されていることに気付くかもしれません。伝統的には一時的なリダイレクトには302が、恒久的なリダイレクトには301が使用されていましたが、多くのブラウザでは元のリクエストメソッドに関係なく、302を使用する際にリダイレクトのリクエストメソッドがPOSTからGETリクエストに変更されていました。

/usersから/peopleへのリダイレクトの例で考えると、新しいユーザーを作成するために/usersPOSTリクエストを行い、302一時的リダイレクトに従うと、リクエストメソッドがPOSTからGETリクエストに変更されます。これは意味がありません。新しいユーザーを作成するには、/peopleに対してGETリクエストではなくPOSTリクエストを行うべきです。

307ステータスコードの導入により、リクエストメソッドはPOSTとして保持されます。

  • 302 - 一時的リダイレクト、リクエストメソッドをPOSTからGETに変更します
  • 307 - 一時的リダイレクト、リクエストメソッドをPOSTとして保持します

redirect()メソッドはデフォルトで302一時的リダイレクトの代わりに307を使用するため、リクエストは常にPOSTリクエストとして保持されます。

HTTPリダイレクトについての詳細はこちら

バージョン履歴

バージョン変更点
v13.0.0redirect 導入時期: