Question

Next 13.4 Error: NEXT_REDIRECT in API routes

My /app/api/auth/route.ts file:

import { redirect } from 'next/navigation';
    
export async function GET(req: Request) {
  try {
    redirect('/dashboard');
  } catch (error) {
    console.log(error);
    redirect('/');
  }
}

I realized that when I do redirect in a try catch, I get the error :

Error: NEXT_REDIRECT
        at getRedirectError (webpack-internal:///(sc_server)/./node_modules/next/dist/client/components/redirect.js:40:19)
        at redirect (webpack-internal:///(sc_server)/./node_modules/next/dist/client/components/redirect.js:46:11)
        at GET (webpack-internal:///(sc_server)/./app/api/auth/route.ts:23:66)
        at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
        at async eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:244:37) {
      digest: 'NEXT_REDIRECT;replace;/dashboard'
    }

When I get get rid of the try catch everything works fine:

export async function GET(req: Request) {
  redirect('/dashboard')
}

This works as expected. I need try and catch because this is an auth route and I need some error handling because the request could fail, I have left out the auth functionalities because I realized that this happens just on a simple try and catch.

Or if Next 13 has another way of error handling in /api routes please let me know.

 46  69015  46
1 Jan 1970

Solution

 36

At the moment, the workaround I found is to not use:

import { redirect } from 'next/navigation';

But to use instead:

import { useRouter } from 'next/navigation'
const router = useRouter()
router.push("/")
2023-07-12

Solution

 36

At the moment, the workaround I found is to not use:

import { redirect } from 'next/navigation';

But to use instead:

import { useRouter } from 'next/navigation'
const router = useRouter()
router.push("/")
2023-07-12

Solution

 30

When using redirect in a server component you should move it to the finally block. Here is how:

export default async function Page() {
    let redirectPath: string | null = null

    try {
        //Rest of the code
        redirectPath = `/dashboard`
    } catch (error) {
        //Rest of the code
        redirectPath = `/`
    } finally {
        //Clear resources
        if (redirectPath)
            redirect(redirectPath)
    }

    return <>{/*Rest of JSX*/}</>
}

From the redirect documentation:

redirect internally throws an error so it should be called outside of try/catch blocks.

In api routes you should use the NextResponse from next/server. Here is how

import { NextRequest, NextResponse } from "next/server";

export function GET(request: NextRequest) {
    try {
        //Code
        return NextResponse.redirect(`<an absolute url>`)
    } catch {
        //Error handling code
        return NextResponse.redirect(`<an absolute url>`)
    } finally {
        //Clear resources
        //No redirect here
    }
}
2023-12-31

Solution

 30

When using redirect in a server component you should move it to the finally block. Here is how:

export default async function Page() {
    let redirectPath: string | null = null

    try {
        //Rest of the code
        redirectPath = `/dashboard`
    } catch (error) {
        //Rest of the code
        redirectPath = `/`
    } finally {
        //Clear resources
        if (redirectPath)
            redirect(redirectPath)
    }

    return <>{/*Rest of JSX*/}</>
}

From the redirect documentation:

redirect internally throws an error so it should be called outside of try/catch blocks.

In api routes you should use the NextResponse from next/server. Here is how

import { NextRequest, NextResponse } from "next/server";

export function GET(request: NextRequest) {
    try {
        //Code
        return NextResponse.redirect(`<an absolute url>`)
    } catch {
        //Error handling code
        return NextResponse.redirect(`<an absolute url>`)
    } finally {
        //Clear resources
        //No redirect here
    }
}
2023-12-31