⛏️

Next.js Server Actionsで redirect() が機能しないときの対処法

に公開

Next.jsのServer Actionsでは、redirect()関数を使って任意のページへ遷移させることができます。しかし、使い方を誤ると意図したリダイレクトが行われず、エラーが発生する場合があります。

この記事では、redirect()の典型的な落とし穴と、その対策について解説します。

よくあるケース

例えば、ユーザーの登録状況を確認し、未登録の場合にリダイレクトさせたいとします。

"use server";

import { redirect } from "next/navigation";
import { isUserRegistered } from "@/lib/user";

export async function submitForm() {
  try {
    const registered = await isUserRegistered();
    if (!registered) {
      redirect("/register"); // 登録ページへリダイレクト
    }

    // 登録済みユーザー向けの処理
    return { status: "success" };
  } catch (error) {
    console.error(error);
    return { status: "error" };
  }
}

このコードではredirect()tryブロック内にあるため、リダイレクトが正常に行われず、代わりに以下のようなエラーが発生します。

Error: NEXT_REDIRECT
digest: 'NEXT_REDIRECT;push;/register;307;'

原因

redirect()は内部的に例外をスローし、Next.jsがそれを捕捉してリダイレクトを実行します。
しかし、try-catchで囲ってしまうと、例外がキャッチされてしまい、リダイレクトが抑制されてしまいます。

解決策

redirect()try-catch外で実行する

export async function submitForm() {
  const registered = await isUserRegistered();
  if (!registered) {
    redirect("/register"); // tryの外に置く
  }

  try {
    // 正常処理
    return { status: "success" };
  } catch (error) {
    return { status: "error" };
  }
}

補足

  • リダイレクト先は絶対パスで指定しましょう(例: /register
  • リダイレクト条件はできるだけ早い段階でチェックしましょう

まとめ

このように、redirect()を使う際はその特殊な挙動を理解する必要があります。

参考

https://nextjs.org/docs/app/api-reference/functions/redirect

https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions

Discussion