Cross Subdomain with .localhost

More details below in the post body
14 Replies
MC
MCOP4w ago
@Better Auth I have an oauth server on localhost:3000 running better auth, localhost:3001 is the user dashboard, x.localhost:3002 is a customer portal I have enabled cross subdomain cookie
advanced: {
crossSubDomainCookies: {
enabled: true,
domain: defaultCookieDomain,
},
defaultCookieAttributes: {
sameSite: "lax",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
domain: ".localhost",
},
},
advanced: {
crossSubDomainCookies: {
enabled: true,
domain: defaultCookieDomain,
},
defaultCookieAttributes: {
sameSite: "lax",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
domain: ".localhost",
},
},
But after login into localhost:3001 when i goto x.localhost:3002 it's not logged in
Better Auth
Better Auth4w ago
Based on your configuration and the behavior you’re describing, it looks like the issue is related to the cookie attributes. When you enable cross‑subdomain cookies with Better Auth, the documentation notes that if you need cookies to work across different subdomains (or origins), you must set the SameSite attribute to "none" (with Secure enabled in production) instead of the default "lax" [3]. In your current setup you have:
defaultCookieAttributes: {
sameSite: "lax",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
domain: ".localhost",
}
defaultCookieAttributes: {
sameSite: "lax",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
domain: ".localhost",
}
Since “lax” will not send the cookie on cross-site requests (which is needed when accessing from x.localhost:3002), switching to:
defaultCookieAttributes: {
sameSite: "none",
secure: process.env.NODE_ENV === "production", // or false for local testing if needed
httpOnly: true,
domain: ".localhost",
}
defaultCookieAttributes: {
sameSite: "none",
secure: process.env.NODE_ENV === "production", // or false for local testing if needed
httpOnly: true,
domain: ".localhost",
}
should allow the browser to include the cookie on requests from your different subdomains. Also, keep in mind that in a purely local environment you might need to adjust the secure flag since HTTPS requirements differ from production. Have you tried updating the SameSite setting to "none" and checking if the cookie is being stored in the browser? Let me know if this helps or if you need more details on any part of the configuration! Sources: [3] Hono Integration | Better Auth — Better Auth is powered by https://clarm.com
Hono Integration | Better Auth
Integrate Better Auth with Hono.
MC
MCOP4w ago
@Better Auth still same
defaultCookieAttributes: {
sameSite: process.env.NODE_ENV === "production" ? "none" : "lax",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
domain: ".localhost",
},
defaultCookieAttributes: {
sameSite: process.env.NODE_ENV === "production" ? "none" : "lax",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
domain: ".localhost",
},
Better Auth
Better Auth4w ago
Hi there! It looks like you’re currently setting your default cookie attributes as follows:
defaultCookieAttributes: {
sameSite: process.env.NODE_ENV === "production" ? "none" : "lax",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
domain: ".localhost",
},
defaultCookieAttributes: {
sameSite: process.env.NODE_ENV === "production" ? "none" : "lax",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
domain: ".localhost",
},
For local development, using a domain value of ".localhost" can sometimes cause issues. Cookies are very particular about the domain attribute—on localhost, many browsers expect either no domain specified or exactly "localhost" (without a leading dot) because the dot is usually used for subdomains in a production scenario. In production, setting the domain to something like ".yourdomain.com" is appropriate if you need subdomain support, but for localhost it’s better to remove this attribute or set it precisely to "localhost" [5]. Could you let me know if you’re testing on a standard localhost setup or if you’re simulating subdomains locally? This will help us fine-tune the recommendation further. Are there any specific issues you’re seeing (like cookies not being set or session not being maintained) that we can troubleshoot together? Sources: [5] Hono Integration | Better Auth — Better Auth is powered by https://clarm.com
Hono Integration | Better Auth
Integrate Better Auth with Hono.
MC
MCOP4w ago
@Better Auth just a localhost, nothing else
Better Auth
Better Auth4w ago
Hey there, it sounds like you’re confirming that you're only using localhost for your development setup. That's totally fine—Better Auth works perfectly on localhost during development! For instance, when setting up features like anonymous auth, Better Auth even recommends using "localhost" to avoid potential conflicts with production domains [1]. Similarly, when configuring passkeys, using "localhost" as your rpID and origin is supported for local development [5]. Are you experiencing any issues with your current localhost configuration, or is there anything specific you’d like to know about setting it up? Sources: [1] feat: use localhost as email domain in anonymous auth [5] Passkey | Better Auth — Better Auth is powered by https://clarm.com
GitHub
Build software better, together
GitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute to over 420 million projects.
From An unknown user
From An unknown user
From An unknown user
GitHub
feat: use localhost as email domain in anonymous auth by typed-si...
Although temporary-{timestamp}-better-auth@email.com is almost impossible to cause conflict, email.com may cause confusion 😕 Maybe the approach from Git is better: localhost. PS: As localhost (actu...
MC
MCOP4w ago
@Better Auth but what's the soltion?
defaultCookieAttributes: {
sameSite: process.env.NODE_ENV === "production" ? "none" : "lax",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
domain: ".localhost",
},
defaultCookieAttributes: {
sameSite: process.env.NODE_ENV === "production" ? "none" : "lax",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
domain: ".localhost",
},
Better Auth
Better Auth4w ago
It looks like the snippet is setting cookie attributes based on NODE_ENV, which is a solid start, but there are a couple of things to keep in mind: 1. In production, if you want to support cross-domain cookies you must set SameSite to "none" and secure to true—which you’re doing—but you need to make sure the domain is a valid domain for production. Setting domain to ".localhost" is generally only appropriate for local development. For production, the domain should match your actual domain (or be left unset so that the browser defaults apply) [5]. 2. For local development, cookies are usually best left with SameSite "lax" (and secure can be false) without explicitly defining a domain. This avoids issues where browsers might reject cookies with an invalid domain value [6]. So the recommended solution is: - In production: Use sameSite: "none", secure: true, and set the domain to your production domain, or preferably let Better Auth auto-adjust it (if your callbackURL and trustedOrigins are set up correctly). - In development: Use sameSite: "lax", secure: false, and omit the domain (or use a valid local domain if absolutely needed). Does that clarify the solution for your configuration, or do you need more help customizing it? Sources: [5] Security | Better Auth [6] Hono Integration | Better Auth — Better Auth is powered by https://clarm.com
Security | Better Auth
Better Auth security features.
Hono Integration | Better Auth
Integrate Better Auth with Hono.
MC
MCOP4w ago
@Better Auth still same problem
advanced: {
crossSubDomainCookies: {
enabled: true,
domain: ".localhost",
},
defaultCookieAttributes: {
sameSite: process.env.NODE_ENV === "production" ? "none" : "lax",
secure: process.env.NODE_ENV === "production" ? true : false,
httpOnly: true,
domain: ".localhost",
},
},
advanced: {
crossSubDomainCookies: {
enabled: true,
domain: ".localhost",
},
defaultCookieAttributes: {
sameSite: process.env.NODE_ENV === "production" ? "none" : "lax",
secure: process.env.NODE_ENV === "production" ? true : false,
httpOnly: true,
domain: ".localhost",
},
},
Better Auth
Better Auth4w ago
It sounds like the issue might be related to the fact that you're using a leading dot (".localhost") in your domain settings. For local development, cookies usually work better when the domain is simply "localhost" without a preceding dot. The Better Auth docs indicate that cross-subdomain cookies are most useful when dealing with actual subdomains (for example, "app.example.com" and "status.example.com") rather than a single domain like localhost [12]. Additionally, note that in your defaultCookieAttributes the sameSite and secure settings depend on your NODE_ENV. When you're in development, you're using "lax" and not secure—which is fine if you're not trying to simulate cross-domain behavior. But if you want to test cross-domain cookie behavior locally, you might need to adjust these settings and ensure your front-end origin exactly matches the domain in your auth config [5]. Have you tried updating the domain to "localhost" (without the leading dot) or removing the domain attribute altogether for local development? Let me know if that change helps or if there's anything else I can assist with! Sources: [5] Hono Integration | Better Auth [12] Cookies | Better Auth — Better Auth is powered by https://clarm.com
Hono Integration | Better Auth
Integrate Better Auth with Hono.
Cookies | Better Auth
Learn how cookies are used in Better Auth.
MC
MCOP4w ago
@Better Auth still same. I updated to "localhost" (removed dot)
Better Auth
Better Auth4w ago
Hi there! It sounds like you've updated your configuration to use "localhost" (without a dot) as suggested, but you're still running into an issue. Based on what we know: • Ensure that your baseURL or email domain is correctly set—remember that Better Auth now enforces protocol validation on the baseURL ([1]). If you're setting it in your environment variables, verify it includes "http://" or "https://".
• Also, if you're modifying the email domain for anonymous auth (as was discussed in Document 6), double-check that all related configurations (for instance, in your .env file and any hardcoded URLs, like in the authClient) are updated accordingly. Could you please share a bit more context on what error is still occurring after the update? Alternatively, if you're not sure where the issue might be, feel free to tag @bekacru or @ping__ so they can dive deeper into your setup. What additional details can you provide about the error messages you're seeing? Sources: [1] fix: validate baseURL protocol and improve error messages — Better Auth is powered by https://clarm.com
GitHub
Build software better, together
GitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute to over 420 million projects.
From An unknown user
From An unknown user
From An unknown user
GitHub
fix: validate baseURL protocol and improve error messages by dmmulr...
Using localhost:3000 (without protocol) as baseURL in env vars caused unclear errors during schema generation. This adds protocol validation with actionable error messages to improve DX. Summary ...
Alex Yang
Alex Yang4w ago
I believe localhost is a special case for browsers. I would recommend that you use sth like cloudflare tunnel that make your localhost to a real domain
Nexus
Nexus3w ago
I'm currently working with better-auth server on localhost:3001 and my frontend on localhost:3000. I'm doing multi-tenancy via subdomain so like customer1.localhost:3000, customer2.localhost:3000 and so on. After a bunch of this setup is working for me in development
advanced: {
crossSubDomainCookies: {
enabled: true,
domain: 'localhost',
},
defaultCookieAttributes: {
secure: true,
httpOnly: true,
sameSite: 'none',
domain: 'localhost',
},
},
trustedOrigins: ['http://localhost:3000', 'http://*.localhost:3000'],
advanced: {
crossSubDomainCookies: {
enabled: true,
domain: 'localhost',
},
defaultCookieAttributes: {
secure: true,
httpOnly: true,
sameSite: 'none',
domain: 'localhost',
},
},
trustedOrigins: ['http://localhost:3000', 'http://*.localhost:3000'],
What's interesting is that I need to set secure: true even though I'm in development. Also, I'm finding myself not needing to add the leading . to the domain on crossSubDomainCookies or defaultCookieAttributes. Not sure how I'll set things up in production, but at least the above gets me going for now. @Alex Yang I found myself stuck on LLMs telling me that browsers don't support subdomains on localhost. However, after some digging I found that they definitely do support it nowadays: https://hackernoon.com/local-development-with-subdomains-mobile-testing-and-oauth-is-it-more-cost-effective

Did you find this page helpful?