コンテンツへスキップ

redirect

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

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

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

参考情報:

  • サーバーアクションおよびルートハンドラでは、`redirect`は`try/catch`ブロックの後に呼び出す必要があります。
  • 307 (一時的) の代わりに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
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
'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
'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
'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`へのリダイレクトの以下の例を考えてみましょう。新しいユーザーを作成するために`/users`に`POST`リクエストを送信し、`302`の一時的なリダイレクトに従う場合、リクエストメソッドは`POST`から`GET`リクエストに変更されます。これは、新しいユーザーを作成するには、`/people`に対して`GET`リクエストではなく`POST`リクエストを行うべきであるため、理にかなっていません。

`307`ステータスコードの導入により、リクエストメソッドが`POST`として保持されるようになりました。

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

`redirect()`メソッドは、デフォルトで`302`の一時的なリダイレクトではなく、`307`を使用します。これは、リクエストが*常に*`POST`リクエストとして保持されることを意味します。

HTTPリダイレクトについてさらに詳しく

バージョン履歴

バージョン変更点
v13.0.0redirectを導入。