Multiple auth0 in single source

Hi auth0 team, thank you for provide such as wonderful product.

While continue providing good experienced to users I got an issue need your aid as I describe below.

My application are host for multiple websites, each website will have its own auth0 configuration.

Currently I use nextjs version 14.2.35, nextjs-auth0 version 3.5.0, which I can create api such as: /login, /callback, /logout, /me, …

Example for /login:

import { getReturnToUrl } from '@/packages/constant/application_meta_data';
import Auth0Instance from '@/packages/constant/auth0_factory';
import { headers } from 'next/headers';
import { NextResponse } from 'next/server';

export async function GET(req: any, res: any) {
  const host = headers().get('host') ?? '';
  const authInstance = Auth0Instance(host);
  const returnTo = getReturnToUrl(host);
  try {
    const response = await authInstance.handleLogin(req, res, {
      authorizationParams: {
        scope: 'openid offline_access email profile',
        prompt: 'login',
      },
      returnTo: returnTo,
    });
    return response;
  } catch (error: any) {
    return NextResponse.json(
      { message: error.message },
      { status: error.status || 400 },
    );
  }
}

authInstance is Auth0Server import from @auth0/nextjs-auth0 .

I want to upgrade mine nextjs-auth0 version to newest which is v4.16.2 but when I do, the function handleLogin, handleLogout, handleProfile, … are not exposed to public and all the route need to be injected via proxy or middleware.

So If I do the upgrade I will lost ability to host multiple websites with different configuration, but If I don’t I won’t able to use newest features like Custom Token Exchange.

Please take a look when you’re available.

Best regard,

Trung Tran

Hi @trung.tran

Welcome to the Auth0 Community!

I am sorry for the delayed response to your inquiry.

I am still investigating the matter and I will come back with an update ASAP.

Otherwise, upgrading your version should not affect the capabilities of your application to host multiple websites with different configurations.

Kind Regards,
Nik

Hi @nik.baleca ,

Thanks for response.

Please help take a look when you available so that I can upgrade to newest version

Kind Regards,

Trung

Hi @nik.baleca ,

Just following up on this case, any updates so far?

Once I have your feedback, I’ll be able to continue processing the rest. Thanks for your help!

Best Regards,

Trung

Hi again!

I am sorry for the delayed reply, I will try to provide an update by EOD or tomorrow with the first chance I get!

Thank you for your patience!

Kind Regards,
Nik

Hi again!

I am again sorry for the delayed response to the issue that you are experiencing.

As far as I have investigated regarding the matter, you will not lose the ability to host multiple websites dynamically with different configurations. The nextjs-auth0 v4 SDK still fully supports multi-tenancy and dynamic instantiation. The reason handleLogin feels “hidden” or broken is simply because v4 changed its function signature to align natively with the Next.js App Router, transforming it from a direct-execution function into a factory function.

  • In v3: handleLogin was an asynchronous function. You passed it the request, response, and your options, and it executed the Auth0 redirect immediately.
  • In v4: The SDK was rewritten to natively support the Next.js App Router’s NextRequest paradigm. Because Next.js App Router handlers are expected to be exported directly (e.g., export const GET = handleAuth() ), the Auth0 SDK methods were converted into higher-order factory functions.

To upgrade to v4.16.2 and keep your dynamic, host-based multi-tenant architecture perfectly intact, you just need to adjust how you invoke the Auth0 instance methods in your API routes.

Instead of awaiting handleLogin(req, res, options) , you call handleLogin(options) to generate the handler, and then immediately execute that generated handler by passing it the NextRequest and the context.

Here is exactly how your /login route translates to v4:

import { getReturnToUrl } from '@/packages/constant/application_meta_data';
import Auth0Instance from '@/packages/constant/auth0_factory'; // Your dynamic initAuth0 factory
import { headers } from 'next/headers';
import { NextRequest, NextResponse } from 'next/server';

export async function GET(req: NextRequest, ctx: any) {
  const host = headers().get('host') ?? '';
  
  const authInstance = Auth0Instance(host); 
  const returnTo = getReturnToUrl(host);
  
  try {
    const loginRouteHandler = authInstance.handleLogin({
      authorizationParams: {
        scope: 'openid offline_access email profile',
        prompt: 'login',
      },
      returnTo: returnTo,
    });

    const response = await loginRouteHandler(req, ctx);
    
    return response;
    
  } catch (error: any) {
    return NextResponse.json(
      { message: error.message },
      { status: error.status || 400 },
    );
  }
}

You can safely apply this exact same two-step pattern to all of your other dynamic routes (/callback , /logout , /me ).
For example, your callback route in v4 will simply look like this:

const callbackRouteHandler = authInstance.handleCallback();
return await callbackRouteHandler(req, ctx);

I would highly recommend checking out the official migration guide provided through the Github repository.
You can also check out this issue that was opened in the past regarding a multi-tenant with subdomains application.

Additionally, I can see that you are part of an enterprise tier subscription. If you have issues during the migration of your application to v4, you can open a support ticket on the matter or open an issue on the Github repository.

If you have any other questions, let me know!

Kind Regards,
Nik

Hi @nik.baleca ,

Thanks for your response

I will follow your instruction

Best regards

Trung