Next.js Discord

Discord Forum

Redirect inside of middleware not updating url

Unanswered
Willow Ptarmigan posted this in #help-forum
Open in Discord
Willow PtarmiganOP
Hey all,

I am running into an issue where I have redirect inside of my middleware to a complete profile flow if a user has to complete some profile information. it seems to work fine, but im finding that after a user signs in and triggers this redirect that the complete profile component is rendered but the url hasnt been updated .

I am using authjs v5, beta 19 to handle my auth and i have put that inside of a form action.

Here is my middleware:
import { NextResponse } from "next/server";
import { auth } from "./auth";
import * as Routes from "@/constants/routes";

const isProtectedRoute = (pathname: string) => {
  return (
    pathname.startsWith(Routes.ADMIN) ||
    pathname.startsWith(Routes.DASHBOARD) ||
    pathname.startsWith(Routes.HOME) ||
    pathname.startsWith(Routes.ACCOUNT) ||
    pathname.startsWith(Routes.SETTINGS) ||
    pathname.startsWith(Routes.COMMISSION_PORTFOLIO)
  );
};

export default auth((req) => {
  console.log("------ auth middleware ------");
  console.log("req.url:", req.url);
  // if the user is not logged in and is trying to access a protected route
  // redirect them to the sign-in page
  if (isOnProtectedRoute && !isLoggedIn) {
    return NextResponse.redirect(new URL(Routes.SIGN_IN, req.nextUrl));
  }

  // if the user is logged in and has not completed their profile
  // redirect them to the complete profile page
  if (isLoggedIn && req.auth?.user.isProfileComplete === false) {
    // check if the user is already on the complete profile page
    // to prevent an infinite redirect loop
    if (req.nextUrl.pathname !== Routes.COMPLETE_PROFILE) {
      return NextResponse.redirect(
        new URL(Routes.COMPLETE_PROFILE, req.nextUrl)
      );
    }
  }

  return NextResponse.next();
});

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
};

35 Replies

Willow PtarmiganOP
This is my server action in my signin form:
"use server";
{.........}
export async function signInAction(
  prevState: SignInActionFormState,
  rawFormData: FormData
): Promise<SignInActionFormState> {
  console.log("signInAction");
  // Convert FormData to object
  const formData = Object.fromEntries(rawFormData);
  const parsed = SignInFormSchema.safeParse(formData);

  console.log("parsed", parsed);

  // get the fields from the form data
  const fields: Record<string, string> = {};
  for (const key of Object.keys(formData)) {
    fields[key] = formData[key].toString();
  }

  // if the form data is invalid, return an error message
  if (!parsed.success) {
    return {
      message: undefined,
      fieldErrors: parsed.error.flatten().fieldErrors,
      fields,
    };
  }

  try {
    const res = await signIn("credentials", {
      username: parsed.data.username,
      password: parsed.data.password,
      redirect: false, // Prevent automatic redirect
    });

    if (res?.error) {
      return { success: false, message: res.error };
    }

    if (res?.url) {
      redirect(res.url);
    }

    // Successful sign-in, redirect to dashboard
    redirect(Routes.DASHBOARD);
  } catch (error) {
    console.log("error in sign in");
    // we are using the error message to determine if this is a redirect
    // from authjs, if it is a redirect, we want to rethrow the error
    // so that nextjs can handle the redirect
    // this is because we are doing a client side redirect inside of a server action
    if (isRedirectError(error)) {
      console.log("error in sign in: NEXT_REDIRECT: ", error);
      // This is a redirect, not an actual error
      throw error;
    }
    console.error("SignIn error:", error);
    return {
      success: false,
      message: "An error occurred during sign in. Please try again later.",
    };
  }
}
when I try and trace what is happening in the middleware this is all im seeing:
------ auth middleware ------
req.url: http://localhost:3000/dashboard
------ auth middleware ------
req.url: http://localhost:3000/sign-up/complete-profile


and as stated above, the page for my profile complete is being rendered but the url is not correct.

Thanks in advance for any help
Willow PtarmiganOP
bump
When redirected in mw you need to use the actual url not localhost it doesn’t resolve local host to the proper spot. I didn’t read through all your code cause I’m on mobile.
Let me know if that helps
Willow PtarmiganOP
when the redirection doesnt have a hard coded host, the logs are from me running the code locally.

In my middleware iam doing this to redirect:
 return NextResponse.redirect(
        new URL(Routes.COMPLETE_PROFILE, req.nextUrl)
      );
So what’s routes.Completeprofile? You shouldn’t need the second argument.
Log those out in something like console.log(“routes.completeProfile\req.nexturl).


On my phone so sorry for typos or code block.
Willow PtarmiganOP
Routes.COMPLETE_PROFILE is a relative route so the second param is needed since i pull the base from the request
I mean still log it out and make sure the URL is valid.
Willow PtarmiganOP
this is the output:
this is using the case of user logs in, calles authjs signin from an action. The action is then redirecting to /dashboard, but the middleware is picking up that they havent finished their profile yet, so it redirects to /sign-up/complete-profile.

then the same issue happen where after this inital signup, the user ui is the contents of /sign-up/complete-profile but the url is /dashboard
I think you need to redirect to the actual url
@Willow Ptarmigan
unless its actually running on local host
middleware is weird, gotta have the actual url cant say localhost
Willow PtarmiganOP
its running on my local machine
Interesting... hrmmm
Can you try just doing the redirect without using new URL() idk if itll make a difference.... lol

something like
return NextResponse.redirect(`${process.env.LocalURL}${redirectCookie.value}`);
Thats what I do in my middleware. Or at the very least to string the new url() object, it might not like it being passed in.
Just spitballing ideas
Willow PtarmiganOP
redirect using hardcoded url results in the same issue
That is really strange... I dont understand how....
Id have to have the repo local to look further into it I think
Or if you can reproduce in a smaller project maybe?
Willow PtarmiganOP
yeah i try and get something up and running i think at smaller scale
Willow PtarmiganOP
I wonder if it has something todo with authjs's middleware wrapper? I tried making. super simple example with out authjs and it seemed to work fine
the only thing im doing different might just be using authjs's auth middleware wrapper
Willow PtarmiganOP
bump
I would reach out on the auth js discord or GitHub. Unfortunately I don’t use any auth library so I am of little help without a lot of work on my part.
Willow PtarmiganOP
yeah ive already posted it over there. just waiting on something actionable
thanks for the help
Willow PtarmiganOP
so still trying to figure this out but I stumbled upon this post:
https://github.com/vercel/next.js/issues/65936
Willow PtarmiganOP
now im wondering if auth middleware redirects are the correct way of dealing with my use case?