Docs

Hono Integration

Before you start, make sure you have a Better Auth instance configured. If you haven't done that yet, check out the installation.

Mount the handler

We need to mount the handler to Hono endpoint.

import { Hono } from "hono";
import { auth } from "./auth";
import { serve } from "@hono/node-server";
import { cors } from "hono/cors";
 
const app = new Hono();
 
app.on(["POST", "GET"], "/api/auth/**", (c) => {
	return auth.handler(c.req.raw);
});
 
serve(app);

Cors

To configure cors, you need to use the cors plugin from hono/cors.

import { Hono } from "hono";
import { auth } from "./auth";
import { serve } from "@hono/node-server";
import { cors } from "hono/cors";
 
const app = new Hono();
 
app.use(
	"/api/auth/**", // or replace with "*" to enable cors for all routes
	cors({
		origin: "http://localhost:3001", // replace with your origin
		allowHeaders: ["Content-Type", "Authorization"],
		allowMethods: ["POST", "GET", "OPTIONS"],
		exposeHeaders: ["Content-Length"],
		maxAge: 600,
		credentials: true,
	}),
);

Middleware

You can add a middleware to save the session and user in a context and also add validations for every route.

import { Hono } from "hono";
import { auth } from "./auth";
import { serve } from "@hono/node-server";
import { cors } from "hono/cors";
 
const app = new Hono<{
	Variables: {
		user: typeof auth.$Infer.Session.user | null;
		session: typeof auth.$Infer.Session.session | null
	}
}>();
 
app.use("*", async (c, next) => {
	const session = await auth.api.getSession({ headers: c.req.raw.headers });
 
  	if (!session) {
    	c.set("user", null);
    	c.set("session", null);
    	return next();
  	}
 
  	c.set("user", session.user);
  	c.set("session", session.session);
  	return next();
});
 
app.on(["POST", "GET"], "/api/auth/**", (c) => {
	return auth.handler(c.req.raw);
});
 
 
serve(app);

This will allow you to access the user and session object in all of your routes.

app.get("/session", async (c) => {
	const session = c.get("session")
	const user = c.get("user")
	
	if(!user) return c.body(null, 401);
 
  	return c.json({
	  session,
	  user
	});
});

Cross-Domain Cookies

By default, all Better Auth cookies are set with SameSite=Lax. If you need to use cookies across different domains, you’ll need to set SameSite=None and Secure=true. However, we recommend using subdomains whenever possible, as this allows you to keep SameSite=Lax. To enable cross-subdomain cookies, simply turn on crossSubDomainCookies in your auth config.

auth.ts
export const auth = createAuth({
  advanced: {
    crossSubDomainCookies: {
      enabled: true
    }
  }
})

If you still need to set SameSite=None and Secure=true, you can adjust these attributes globally through cookieOptions in the createAuth configuration.

auth.ts
export const auth = createAuth({
  advanced: {
    defaultCookieAttributes: {
      sameSite: "none",
      secure: true
    }
  }
})

You can also customize cookie attributes individually by setting them within cookies in your auth config.

auth.ts
export const auth = createAuth({
  advanced: {
    cookies: {
      sessionToken: {
        sameSite: "none",
        secure: true
      }
    }
  }
})

On this page