コンテンツにスキップ

redirect

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

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

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

リファレンス

Parameters

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

redirect(path, type)
パラメータタイプ説明
pathstringリダイレクト先の 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 エラーがスローされ、それがスローされたルートセグメントのレンダリングが終了します。

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 へのリダイレクトを例にとると、新しいユーザーを作成するために POST リクエストを /users に送信し、302 の一時的なリダイレクトに従う場合、リクエストメソッドは POST から GET に変更されます。これは、新しいユーザーを作成するには /peoplePOST リクエストを送信する必要があり、GET リクエストではないため、理にかなっていません。

307 ステータスコードの導入により、リクエストメソッドが POST のまま維持されるようになります。

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

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

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

バージョン履歴

バージョン変更履歴
v13.0.0redirect が導入されました。