i cant set different basePath for each of my clients because the server instance require a basePath #1508

Closed
opened 2026-03-13 08:44:17 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @lord007tn on GitHub (Jul 16, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

auth.ts

export const auth = betterAuth({
  database: prismaAdapter(prisma, {
    provider: 'postgresql',
  }),
  emailAndPassword: {
    enabled: true,
  },
  baseURL: keys().VITE_API_SERVER_URL,
  basePath: '/api/admin/auth', // this is needed or my hono server will return 404
  secret: keys().BETTER_AUTH_SECRET,
  hooks: {
    before: createAuthMiddleware(async (ctx) => {
      console.log('Auth middleware triggered:', ctx.path);
      return;
    }),
  },
  logger: {
    level: 'info',
  },
  advanced: {
    database: {
      generateId: false,
    },
    crossSubDomainCookies: {
      enabled: true,
    },
  },
  user: {
    fields: {
      name: 'fullName',
    },
  },
  plugins: [
    nextCookies(),
    admin({
      defaultRole: SystemRoles.USER,
      adminRoles: [SystemRoles.ADMIN, SystemRoles.SUPER_ADMIN, SystemRoles.SUPPORT],
      schema: {
        session: {
          fields: {
            impersonatedBy: 'impersonatorId',
          },
        },
        user: {
          fields: {
            role: 'systemRole',
          },
        },
      },
    }),
    openAPI(),
  ],
});

client.ts

import { createAuthClient } from 'better-auth/vue';
import { keys } from './keys';

export const { signIn, signOut, signUp, useSession } = createAuthClient({
  baseURL: keys().VITE_API_SERVER_URL,
  basePath: '/api/app/auth',
});

admin-client.ts

import { adminClient } from 'better-auth/client/plugins';
import { createAuthClient } from 'better-auth/vue';
import { keys } from './keys';

export const { signIn, signOut, signUp, useSession } = createAuthClient({
  baseURL: keys().VITE_API_SERVER_URL,
  basePath: '/api/admin/auth',
  plugins: [adminClient()],
});

routes/admin/index.ts


const adminHandler = new Hono<HonoEnv>()
  .on(['POST', 'GET'], '/auth/*', (c) => {
    return auth.handler(c.req.raw);
  })

routes/app/index.ts


const appHandler = new Hono<HonoEnv>()
  .on(['POST', 'GET'], '/auth/*', (c) => {
    return auth.handler(c.req.raw);
  })

routes/index.ts

const app = new Hono<HonoEnv>()
  .route('/admin', adminRoutes)
  .route('/app', appRoutes)

export default app;

i need seperated auth because admins have their own client app ( admin.example.com ) and users have their own client app ( app.example.com ) each on its own subdomain
and the server will be in ( api.example.com )

if there is a better way to handle the auth for seperated apps than the one i provided please tell me

Current vs. Expected behavior

no need for basePath in auth.ts and rely only one the app.on() definition

What version of Better Auth are you using?

1.2.12

Provide environment information

- Windows 11
- Nodejs 22.17.0

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)


Additional context

No response

Originally created by @lord007tn on GitHub (Jul 16, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce auth.ts ```ts export const auth = betterAuth({ database: prismaAdapter(prisma, { provider: 'postgresql', }), emailAndPassword: { enabled: true, }, baseURL: keys().VITE_API_SERVER_URL, basePath: '/api/admin/auth', // this is needed or my hono server will return 404 secret: keys().BETTER_AUTH_SECRET, hooks: { before: createAuthMiddleware(async (ctx) => { console.log('Auth middleware triggered:', ctx.path); return; }), }, logger: { level: 'info', }, advanced: { database: { generateId: false, }, crossSubDomainCookies: { enabled: true, }, }, user: { fields: { name: 'fullName', }, }, plugins: [ nextCookies(), admin({ defaultRole: SystemRoles.USER, adminRoles: [SystemRoles.ADMIN, SystemRoles.SUPER_ADMIN, SystemRoles.SUPPORT], schema: { session: { fields: { impersonatedBy: 'impersonatorId', }, }, user: { fields: { role: 'systemRole', }, }, }, }), openAPI(), ], }); ``` client.ts ```ts import { createAuthClient } from 'better-auth/vue'; import { keys } from './keys'; export const { signIn, signOut, signUp, useSession } = createAuthClient({ baseURL: keys().VITE_API_SERVER_URL, basePath: '/api/app/auth', }); ``` admin-client.ts ```ts import { adminClient } from 'better-auth/client/plugins'; import { createAuthClient } from 'better-auth/vue'; import { keys } from './keys'; export const { signIn, signOut, signUp, useSession } = createAuthClient({ baseURL: keys().VITE_API_SERVER_URL, basePath: '/api/admin/auth', plugins: [adminClient()], }); ``` routes/admin/index.ts ```ts const adminHandler = new Hono<HonoEnv>() .on(['POST', 'GET'], '/auth/*', (c) => { return auth.handler(c.req.raw); }) ``` routes/app/index.ts ```ts const appHandler = new Hono<HonoEnv>() .on(['POST', 'GET'], '/auth/*', (c) => { return auth.handler(c.req.raw); }) ``` routes/index.ts ```ts const app = new Hono<HonoEnv>() .route('/admin', adminRoutes) .route('/app', appRoutes) export default app; ``` i need seperated auth because admins have their own client app ( admin.example.com ) and users have their own client app ( app.example.com ) each on its own subdomain and the server will be in ( api.example.com ) if there is a better way to handle the auth for seperated apps than the one i provided please tell me ### Current vs. Expected behavior no need for basePath in auth.ts and rely only one the app.on() definition ### What version of Better Auth are you using? 1.2.12 ### Provide environment information ```bash - Windows 11 - Nodejs 22.17.0 ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript ``` ### Additional context _No response_
GiteaMirror added the hono label 2026-03-13 08:44:17 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jul 16, 2025):

Hi @lord007tn! I'm Dosu and I’m helping the better-auth team.

Better Auth only supports a single basePath per server instance; it doesn't natively support multiple basePaths or dynamic routing based on subdomain or path. This is because the basePath is used to mount all auth routes and is set once during initialization, so you can't rely solely on your Hono route definitions for separation—Better Auth needs to know its basePath up front for correct routing and trusted origin handling (source).

For your use case (separate admin and user apps on different subdomains), there are two main approaches:

  1. Run multiple Better Auth instances: Each with its own basePath (e.g., /api/admin/auth and /api/app/auth), sharing the same database/storage. You'd mount each instance at the appropriate route in your Hono server.

  2. Use the MCP/OAuth2 pattern: Better Auth's Multi-Client Provider (MCP) plugin is designed for multi-app scenarios. You'd run a single Better Auth instance at a central basePath (like /api/auth) and use OAuth2 flows to distinguish between clients. This is the recommended approach for centralized auth with multiple frontends (source).

Cross-subdomain cookies are supported, but this only affects session sharing, not routing logic.

There isn't a built-in way to have Better Auth dynamically handle multiple basePaths per instance. If you want truly separated endpoints, you'll need to instantiate and mount multiple auth handlers, each with its own config and basePath. If you want a single endpoint for all apps, consider the MCP/OAuth2 approach.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Join Discord Share on X

@dosubot[bot] commented on GitHub (Jul 16, 2025): <!-- Greeting --> Hi @lord007tn! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> Better Auth only supports a single basePath per server instance; it doesn't natively support multiple basePaths or dynamic routing based on subdomain or path. This is because the basePath is used to mount all auth routes and is set once during initialization, so you can't rely solely on your Hono route definitions for separation—Better Auth needs to know its basePath up front for correct routing and trusted origin handling [(source)](https://github.com/better-auth/better-auth/blob/7364c169f6de0eec4f095112047e23480b240078/packages/better-auth/src/types/options.ts). For your use case (separate admin and user apps on different subdomains), there are two main approaches: 1. **Run multiple Better Auth instances**: Each with its own basePath (e.g., `/api/admin/auth` and `/api/app/auth`), sharing the same database/storage. You'd mount each instance at the appropriate route in your Hono server. 2. **Use the MCP/OAuth2 pattern**: Better Auth's Multi-Client Provider (MCP) plugin is designed for multi-app scenarios. You'd run a single Better Auth instance at a central basePath (like `/api/auth`) and use OAuth2 flows to distinguish between clients. This is the recommended approach for centralized auth with multiple frontends [(source)](https://github.com/better-auth/better-auth/blob/7364c169f6de0eec4f095112047e23480b240078/packages/better-auth/src/plugins/mcp/index.ts). Cross-subdomain cookies are supported, but this only affects session sharing, not routing logic. There isn't a built-in way to have Better Auth dynamically handle multiple basePaths per instance. If you want truly separated endpoints, you'll need to instantiate and mount multiple auth handlers, each with its own config and basePath. If you want a single endpoint for all apps, consider the MCP/OAuth2 approach. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/9b2fc8be-5ce9-4b0a-90c0-32e7267ccce4?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/9b2fc8be-5ce9-4b0a-90c0-32e7267ccce4?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/9b2fc8be-5ce9-4b0a-90c0-32e7267ccce4?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/9b2fc8be-5ce9-4b0a-90c0-32e7267ccce4?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/9b2fc8be-5ce9-4b0a-90c0-32e7267ccce4?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/9b2fc8be-5ce9-4b0a-90c0-32e7267ccce4?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/9b2fc8be-5ce9-4b0a-90c0-32e7267ccce4?feedback_type=other)</sup>&nbsp;&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/3409)
Author
Owner

@Kinfe123 commented on GitHub (Jul 16, 2025):

for now the first options i mean this should work - Run multiple Better Auth instances: Each with its own basePath (e.g., /api/admin/auth and /api/app/auth), sharing the same database/storage. You'd mount each instance at the appropriate route in your Hono server. Even if you want to do that , it makes sense for the admin and client to have their own config unless you are gonna ended up on adding a lot of unnecessary cases. and make sure to have a commen shared config for the admin and app if you want.

@Kinfe123 commented on GitHub (Jul 16, 2025): for now the first options i mean this should work - Run multiple Better Auth instances: Each with its own basePath (e.g., /api/admin/auth and /api/app/auth), sharing the same database/storage. You'd mount each instance at the appropriate route in your Hono server. Even if you want to do that , it makes sense for the admin and client to have their own config unless you are gonna ended up on adding a lot of unnecessary cases. and make sure to have a commen shared config for the admin and app if you want.
Author
Owner

@lord007tn commented on GitHub (Jul 17, 2025):

for now the first options i mean this should work - Run multiple Better Auth instances: Each with its own basePath (e.g., /api/admin/auth and /api/app/auth), sharing the same database/storage. You'd mount each instance at the appropriate route in your Hono server. Even if you want to do that , it makes sense for the admin and client to have their own config unless you are gonna ended up on adding a lot of unnecessary cases. and make sure to have a commen shared config for the admin and app if you want.

thats what i ended up doing

could we have that in docs in guides so people understand better the situation here ?

@lord007tn commented on GitHub (Jul 17, 2025): > for now the first options i mean this should work - Run multiple Better Auth instances: Each with its own basePath (e.g., /api/admin/auth and /api/app/auth), sharing the same database/storage. You'd mount each instance at the appropriate route in your Hono server. Even if you want to do that , it makes sense for the admin and client to have their own config unless you are gonna ended up on adding a lot of unnecessary cases. and make sure to have a commen shared config for the admin and app if you want. thats what i ended up doing could we have that in docs in guides so people understand better the situation here ?
Author
Owner

@Kinfe123 commented on GitHub (Jul 17, 2025):

will be there soon.

@Kinfe123 commented on GitHub (Jul 17, 2025): will be there soon.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1508