Next.js Discord

Discord Forum

Nextjs Redirect Error

Answered
Silver carp posted this in #help-forum
Open in Discord
Silver carpOP
Morning guys, how I use NextJs Redirect inside axios interceptor?
Like

import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'

export async function authInterceptorResponseError(error: AxiosError) {
  const { response } = error

  if (response?.status === 401) {
    cookies().delete(AUTH_COOKIE)

    if (typeof window === 'undefined') {
      redirect('/login')
    } else {
      window.location.href = '/login'
    }
  }

  return Promise.reject(error)
}



it is giving an error

{
  digest: 'NEXT_REDIRECT;replace;/login;303;',
  mutableCookies: p {
    _parsed: Map(3) {
      'tenant' => [Object],
      'user-info' => [Object],
      'auth' => [Object]
    },
    _headers: Headers {
      'set-cookie': 'my-cookies-infos; Path=/, auth=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT'
    }
  }
}
Answered by Silver carp
my interceptor
import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'

import { AUTH_COOKIE } from '@/utils/constants'

import type { AxiosError, InternalAxiosRequestConfig } from 'axios'

export async function authInterceptorRequest(
  config: InternalAxiosRequestConfig,
) {
  const token = cookies().get(AUTH_COOKIE)?.value

  if (token) {
    Object.assign(config.headers || {}, {
      authorization: `Bearer ${token}`,
    })
  }

  return config
}

export async function authInterceptorResponseError(error: AxiosError) {
  const { response } = error

  if (response?.status === 401) {
    cookies().delete(AUTH_COOKIE)

    if (typeof window !== 'undefined') {
      window.location.href = '/login'
    }
  }

  return Promise.reject(error)
}

export async function authInterceptorResponseErrorServerSide(
  error: AxiosError,
) {
  'use server'

  const { response } = error

  if (response?.status === 401) {
    cookies().delete(AUTH_COOKIE)

    if (typeof window === 'undefined') {
      redirect('/login')
    }
  }
}
View full answer

40 Replies

Silver carpOP
But the window is undefined, the request that falls into the interceptor comes from a server action
I'm confused 🤔
accessing the window api and redirect at the same time is problematic
u are basically deleting the auth cookie on the serverside and redirecting the user
unless ur your cookie is not http only u can do that on the clientside aswell
Silver carpOP
I don't know how I could do this, within my page.tsx a request is made using server action, which uses axios. What I wanted to do is that when making a request in a server action or on the client side using axios and it returned 401 it would be redirected to login
the state is returned from the serveraction
that would be the client approach
u can do the same without returning any error, just delete the cookie and redirect the user directly using a server action (Which can also be problematic)
Silver carpOP
In this case I can't use axios with server actions? I would like to use axios with server action instead of Fetch API
@Silver carp In this case I can't use axios with server actions? I would like to use axios with server action instead of Fetch API
well u can but i dont really know in what case u benefit from that
Silver carpOP
I would like to centralize the axios error response, when giving 401 return to login
@Silver carp I would like to centralize the axios error response, when giving 401 return to login
so i guess it only applies to your login or register endpoint right?
(server action)
Silver carpOP
This would apply to all requests made to my application.
Because there is a middleware that checks the protection of public and private routes based on the token, if the user's token has expired, he will be left without a token and must return to the login
But I understand that I can't use redirect inside the axios interceptor, but I don't see how I could write this logic
@Silver carp But I understand that I can't use redirect inside the axios interceptor, but I don't see how I could write this logic
why dont u redirect using window directly without using redirect from next
remove if else and only have window.location
Silver carpOP
window is undefined
@Silver carp window is undefined
then check if the window is defined and only then href
if (typeof window !== 'undefined')
Silver carpOP
But in this case it will never redirect to login
@Silver carp But in this case it will never redirect to login
so is this interceptor designed to only work on the serverside or what
this looks a bit better
maybe u could take a look at that
Silver carpOP
Could I write something like this?

export async function authInterceptorResponseError(error: AxiosError) {
  const { response } = error

  if (response?.status === 401) {
    cookies().delete(AUTH_COOKIE)

    if (typeof window !== 'undefined') {
      window.location.href = '/login'
    }
  }

  return Promise.reject(error)
}

export async function authInterceptorResponseErrorServerSide(
  error: AxiosError,
) {
  'use server'

  const { response } = error

  if (response?.status === 401) {
    cookies().delete(AUTH_COOKIE)

    if (typeof window === 'undefined') {
      redirect('/login')
    }
  }
}
Silver carpOP
Yes, just a moment.
I actually won't be able to share all the code, what I can share is

- my page


action.ts
'use server'

import { AxiosError } from 'axios'

import { usersService } from '@/services/http/usersService'

import type { ChangePasswordParams } from '@/services/http/usersService/changePassword'

export async function changePassword(params: ChangePasswordParams) {
  if (!Object.values(params).every((value) => Boolean(value))) {
    return {
      success: false,
      message: 'Campos obrigatórios faltantes',
    }
  }

  const { registration, password, newPassword } = params

  try {
    await usersService.changePassword({ registration, password, newPassword })
    return {
      success: true,
    }
  } catch (error) {
    console.log('error: ', error)
    const message = 'Tente novamente mais tarde'
    if (error instanceof AxiosError) {
      const { response } = error

      return {
        success: false,
        message: response?.data?.message || message,
      }
    }

    return {
      success: false,
      message,
    }
  }
}
Silver carpOP
my interceptor
import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'

import { AUTH_COOKIE } from '@/utils/constants'

import type { AxiosError, InternalAxiosRequestConfig } from 'axios'

export async function authInterceptorRequest(
  config: InternalAxiosRequestConfig,
) {
  const token = cookies().get(AUTH_COOKIE)?.value

  if (token) {
    Object.assign(config.headers || {}, {
      authorization: `Bearer ${token}`,
    })
  }

  return config
}

export async function authInterceptorResponseError(error: AxiosError) {
  const { response } = error

  if (response?.status === 401) {
    cookies().delete(AUTH_COOKIE)

    if (typeof window !== 'undefined') {
      window.location.href = '/login'
    }
  }

  return Promise.reject(error)
}

export async function authInterceptorResponseErrorServerSide(
  error: AxiosError,
) {
  'use server'

  const { response } = error

  if (response?.status === 401) {
    cookies().delete(AUTH_COOKIE)

    if (typeof window === 'undefined') {
      redirect('/login')
    }
  }
}
Answer
Silver carpOP
From what I saw, there isn't a very nice solution, I'm going to do the redirect inside the server action.

Thank you for your time @gin