Astro Auth with Better Auth and Google Signin
1/27/2025
Enable authentication in Astro via Better Auth

Introduction

This guide will guide you step by step on how to enable authentication using Better Auth with Astro. Better auth is an authentication framework that supports various authentication method and is framework agnostic as well. This guide will have Google Authentication as the provider but you can add other provider once Better Auth is installed.

We recommend using Better Auth compared to other solution like Auth.js

Add Better Auth To Astro

To start, install better auth with npm as shown below

Terminal window
npm install better-auth

Initialize/Configure Better Auth

This is important, you need to initialize Better Auth config and database tables for the next steps to work.

Create an auth instance. For this example, we will be using sqlite3.

src/lib/auth.ts
import { betterAuth } from "better-auth";
import Database from "better-sqlite3";
export const auth = betterAuth({
database: new Database(import.meta.env.DB_FILE),
})

Ensure you define DB_FILE. For development, create a file under your Astro root project called .env

.env
DB_FILE=/path/to/file/project.db

Note: project.db file does not have to exists, it will be automatically created.

Run the following command to initialize the sqlite database under your astro root folder

Initialize the database
npx @better-auth/cli migrate

auth Route Handler

We then need to create the catch all route handler used by better-auth

page/api/auth/[...all].ts
import { auth } from "../../../lib/auth";
import type { APIRoute } from "astro";
export const ALL: APIRoute = async (ctx) => {
return auth.handler(ctx.request)
}

Configuring the Google Provider

Now that we have Better Auth setup, we need to configure an auth provider. For this guide we will use the Google Provider. For this we need 2 things

  1. clientId
  2. clientSecret

First, let us setup the provider. Edit the file src/lib/auth.ts and add the google provider as shown below

src/lib/auth.ts
import { betterAuth } from "better-auth";
import Database from "better-sqlite3";
export const auth = betterAuth({
database: new Database(import.meta.env.DB_FILE),
socialProviders: {
google: {
clientId: import.meta.env.GOOGLE_CLIENT_ID || '',
clientSecret: import.meta.env.GOOGLE_CLIENT_SECRET || ''
}
}
})

Acquiring Google Client Id and Client Secret

We need to create Google Client Id and Client Secret in Google’s Cloud Console. This is under the Google Auth Platform. Folow the steps below to generate.

  1. Visit Google Cloud Console - Clients
  2. Ensure you are under the project where you are using the auth for
  3. Click on Create Client
  4. on Application Type, set Web application
  5. Set a Name for the Client
  6. for Authorised JavaScript origins add http://127.0.0.1
  7. for Authorised redirect URIs add http://127.0.0.1:4321/api/auth/callback/google

Save the client.

On the main clients page, click on the Client Name and on the right side, you should see Client ID and Client Secret. Copy them and edit .env file under your astro project

.env
DB_FILE=/path/to/file/project.db
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...

Create the Signin Frontend Flow

Lets create a frontend page that users will click to start the signin process. We will use astro but you can also other framework components in Astro if you want. We will create a plain page, style it as needed.

src/lib/auth-client.ts
import { createAuthClient } from 'better-auth/client';
export const authClient = createAuthClient();
export const { signIn, signOut } = authClient;

Then lets create the page signin.astro

src/page/signin.astro
---
---
<button id='signin'>Sign in with Google</button>
<script>
const { signIn } = await import("../lib/auth-client")
const signinEl = document.getElementById("signin") as HTMLButtonElement
signinEl.onclick = () => signIn.social({
provider: "google",
callbackURL: "/dashboard",
})
</script>

When the user successfully sign in, he/shee will be redirected at /dashboard. Lets create the dashboard page

src/page/dashboard/index.astro
---
import Layout from "../../layouts/Layout.astro";
import { auth } from "../../lib/auth";
export const prerender = false;
const session = await auth.api.getSession({
headers: Astro.request.headers,
});
if (!session) {
return Astro.redirect('/signin')
}
---
<Layout>
<div>You are in {session.user.email}</div>
</Layout>

Conclusion

That is it. You can add other providers as needed. Check the better-auth documentation for more info.