bao
Framework guides

Astro

Add bao authentication to an Astro SSR site — client setup, middleware, and protected pages.

Astro must be configured for SSR (output: "server" or output: "hybrid") to access sessions server-side. Static mode only supports client-side auth.

Install

npm install better-auth

Create the auth client

// src/lib/auth-client.ts
import { createAuthClient } from "better-auth/client";

export const authClient = createAuthClient({
  baseURL: import.meta.env.AUTH_SERVICE_URL,
});

Add to .env:

AUTH_SERVICE_URL=https://my-app-production.workers.dev

Get the session in a page

---
// src/pages/dashboard.astro
const res = await fetch(
  `${import.meta.env.AUTH_SERVICE_URL}/api/auth/get-session`,
  { headers: Astro.request.headers },
);
const session = await res.json();

if (!session?.user) return Astro.redirect("/login");
---

<p>Hello {session.user.email}</p>

Protect routes with middleware

// src/middleware.ts
import { defineMiddleware } from "astro:middleware";

const PROTECTED = ["/dashboard"];

export const onRequest = defineMiddleware(async (context, next) => {
  const isProtected = PROTECTED.some((path) =>
    context.url.pathname.startsWith(path),
  );
  if (!isProtected) return next();

  const res = await fetch(
    `${import.meta.env.AUTH_SERVICE_URL}/api/auth/get-session`,
    { headers: context.request.headers },
  );
  const session = await res.json();

  if (!session?.user) return context.redirect("/login");

  context.locals.user = session.user;
  return next();
});

Running on Cloudflare Workers

If you deploy your Astro site on Cloudflare Pages, consider using a Service Binding to call the bao auth Worker directly with zero HTTP overhead.

CORS

Add your Astro origin to bao.config.json — see CORS configuration.