next.jsvercelauth0

Unresolvable Silent Crash with handleAuth on Vercel (Next.js App Router)


I am facing a challenging debugging journey and its solution for an issue with @auth0/nextjs-auth0 on Vercel with the Next.js App Router.

Core Framework & Auth Libraries:

Database & API Libraries:

The Initial Problem

My application worked perfectly on localhost. However, when deployed to production on Vercel, the login flow would fail silently.

  1. A user would access a protected page (e.g., /dashboard).
  2. Our middleware would correctly detect no session and issue a 307 redirect to /api/auth/login.
  3. The browser's URL would change, but the request would hang. The page never redirected to the Auth0 Universal Login.
  4. There were no errors in the browser console, no crash logs in the Vercel function, and no log entries at all in our Auth0 Dashboard. This proved the crash was happening entirely within the Vercel function before it could ever contact Auth0.

The Debugging Journey: What We Ruled Out

We exhaustively checked every common cause of this issue:

The Core Issue: The SDK Handlers were Failing

To isolate the issue, we were forced to implement a fully manual authentication flow, completely bypassing the SDK's handleLogin and handleCallback functions. This manual process, while complex, is the only thing that works in our production environment.

Our manual flow consists of:

  1. A manual login route (/api/auth/manual-login): This route manually constructs the full Auth0 /authorize URL, encodes our desired returnTo path into the state parameter, and redirects the user. This step was successful.
  2. A manual callback route (/api/auth/manual-callback): This route receives the code from Auth0, manually performs the server-to-server POST request to the /oauth/token endpoint, and upon success, uses the jose library to create its own secure, JWE-encrypted session cookie. Finally, it decodes the state parameter and performs the redirect to the user's original destination.

We are reaching out to the community because this solution feels unsustainable and overly complex. It required us to essentially reinvent the core functionality of the SDK, including session management and encryption, just to get a basic login to work on Vercel.

The Most Baffling Symptoms

Throughout this process, two key behaviors made debugging nearly impossible:

Any help we can get to look into this to know what could be the issue that we missed out? Appreciate the help.


Solution

  • After hours of debugging and narrowing down the issues, ended up it was because of vercel.json which unknowingly trying to rewrite all paths..."catch-all" rewrite rule could be intercepting requests to /api/auth/login and incorrectly serving the main application page

    {  "rewrites": [    { "source": "/:path*", "destination": "/" }  ]}
    

    We were checking earlier with build logs show the functions being created, hence we didn't expect this. Didn't realise that during the npm run build process, Vercel's system correctly analyzes our Next.js project. It sees our app/api/... files and successfully builds them into Serverless Functions. The build process does not look at the vercel.json rewrites. This is why the build log looks perfect.

    and this is different in Runtime: When a user's browser makes a request to https://<our-domain>/api/auth/login, it hits Vercel's Edge Network. The very first thing Vercel does is process the rules in vercel.json.

    So lesson learned: Check your vercel rewrite rules!