Can I share client API routes across subdomains?

I have a monorepo setup and trying to use one app's API routes from another app. (For example, calling localhost:3000's routes from localhost:3001. In production, it will be calling app.domain.com's routes from admin.domain.com) I faced the cors error as expected in local development. Tried to fix it by adding mode: "no-cors":
createAuthClient({
baseURL: [localhost:3000 | app.domain.com],
plugins: [...],
fetchOptions: {
mode: "no-cors",
},
});
createAuthClient({
baseURL: [localhost:3000 | app.domain.com],
plugins: [...],
fetchOptions: {
mode: "no-cors",
},
});
But it didn't work and still getting this error:
ERROR [Better Auth]: TypeError [TypeError: Cannot create property 'callbackURL' on string '{"provider":"github","callbackURL":"/"}']
ERROR [Better Auth]: TypeError [TypeError: Cannot create property 'callbackURL' on string '{"provider":"github","callbackURL":"/"}']
12 Replies
bekacru
bekacru•3w ago
remove no-cors. it should work just make sure to configure your server for cors. Make sure not to use wild card origins and to enabled credentials
nainglinnkhant
nainglinnkhantOP•3w ago
When I remove no-cors, I get the cors error as below:
Access to fetch at 'http://localhost:3001/api/auth/sign-in/social' from origin 'http://localhost:3002' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Access to fetch at 'http://localhost:3001/api/auth/sign-in/social' from origin 'http://localhost:3002' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
My server config is as below. Do I need to add or change anything to make it work?
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: "pg",
usePlural: true,
}),
user: {
changeEmail: {
enabled: true,
sendChangeEmailVerification,
},
},
advanced: {
generateId: false,
},
trustedOrigins: [env.NEXT_PUBLIC_WEB_URL, env.NEXT_PUBLIC_ADMIN_URL],
socialProviders: {
google: {
clientId: env.GOOGLE_CLIENT_ID,
clientSecret: env.GOOGLE_CLIENT_SECRET,
},
github: {
clientId: env.GITHUB_CLIENT_ID,
clientSecret: env.GITHUB_CLIENT_SECRET,
},
},
databaseHooks: {
user: {
create: {
after: afterUserCreated,
},
},
session: {
create: {
before: beforeSessionCreated,
},
},
},
plugins: [
nextCookies(),
organization({
sendInvitationEmail,
}),
admin(),
magicLink({
sendMagicLink,
}),
oAuthProxy(),
customSession(customizeSession),
],
});
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: "pg",
usePlural: true,
}),
user: {
changeEmail: {
enabled: true,
sendChangeEmailVerification,
},
},
advanced: {
generateId: false,
},
trustedOrigins: [env.NEXT_PUBLIC_WEB_URL, env.NEXT_PUBLIC_ADMIN_URL],
socialProviders: {
google: {
clientId: env.GOOGLE_CLIENT_ID,
clientSecret: env.GOOGLE_CLIENT_SECRET,
},
github: {
clientId: env.GITHUB_CLIENT_ID,
clientSecret: env.GITHUB_CLIENT_SECRET,
},
},
databaseHooks: {
user: {
create: {
after: afterUserCreated,
},
},
session: {
create: {
before: beforeSessionCreated,
},
},
},
plugins: [
nextCookies(),
organization({
sendInvitationEmail,
}),
admin(),
magicLink({
sendMagicLink,
}),
oAuthProxy(),
customSession(customizeSession),
],
});
@bekacru could you please check this? : )
bekacru
bekacru•3w ago
share your cors config
nainglinnkhant
nainglinnkhantOP•3w ago
you mean crossSubDomainCookies? If you mean other cors config, could you please tell me how to configure?
bekacru
bekacru•3w ago
what framework are you using?
nainglinnkhant
nainglinnkhantOP•3w ago
I'm using nextjs 15 @bekacru It worked after manually modifying the header of GET and POST route handlers. But for social sign-ins, it still redirects to the original baseURL (for example, I call the localhost:3001's API route from localhost:3002 and after sign-in is successful, it redirects to the localhost:3001 instead of localhost:3002). I get that it's the expected behavior. But is there any way to change it? I tried setting callbackURL like below but doesn't work.
await signIn.social({
provider: "github",
callbackURL: "http://localhost:3002",
});
await signIn.social({
provider: "github",
callbackURL: "http://localhost:3002",
});
bekacru
bekacru•3w ago
this should work. Make sure it's in a trusted origin.
nainglinnkhant
nainglinnkhantOP•3w ago
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: "pg",
usePlural: true,
}),
user: {
changeEmail: {
enabled: true,
sendChangeEmailVerification,
},
},
advanced: {
generateId: false,
},
trustedOrigins: [env.NEXT_PUBLIC_WEB_URL, env.NEXT_PUBLIC_ADMIN_URL],
socialProviders: {
google: {
clientId: env.GOOGLE_CLIENT_ID,
clientSecret: env.GOOGLE_CLIENT_SECRET,
},
github: {
clientId: env.GITHUB_CLIENT_ID,
clientSecret: env.GITHUB_CLIENT_SECRET,
},
},
databaseHooks: {
user: {
create: {
after: afterUserCreated,
},
},
session: {
create: {
before: beforeSessionCreated,
},
},
},
plugins: [
nextCookies(),
organization({
sendInvitationEmail,
}),
admin(),
magicLink({
sendMagicLink,
}),
oAuthProxy(),
customSession(customizeSession),
],
});
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: "pg",
usePlural: true,
}),
user: {
changeEmail: {
enabled: true,
sendChangeEmailVerification,
},
},
advanced: {
generateId: false,
},
trustedOrigins: [env.NEXT_PUBLIC_WEB_URL, env.NEXT_PUBLIC_ADMIN_URL],
socialProviders: {
google: {
clientId: env.GOOGLE_CLIENT_ID,
clientSecret: env.GOOGLE_CLIENT_SECRET,
},
github: {
clientId: env.GITHUB_CLIENT_ID,
clientSecret: env.GITHUB_CLIENT_SECRET,
},
},
databaseHooks: {
user: {
create: {
after: afterUserCreated,
},
},
session: {
create: {
before: beforeSessionCreated,
},
},
},
plugins: [
nextCookies(),
organization({
sendInvitationEmail,
}),
admin(),
magicLink({
sendMagicLink,
}),
oAuthProxy(),
customSession(customizeSession),
],
});
my auth server config already has trustedOrigins configured
bekacru
bekacru•3w ago
so you have 2 differnt nextjs projects?
nainglinnkhant
nainglinnkhantOP•3w ago
yes, my plan is to use one app's auth routes from another app
bekacru
bekacru•3w ago
im not sure why this is working. It should redirect back to callback url unless some error happens. In which case, you should specefic errorCallbackURL instead.
nainglinnkhant
nainglinnkhantOP•2w ago
I see, thanks for your time! 🙌

Did you find this page helpful?