Better Auth
Authentication with Better Auth in your matt-init project
What's Included
Pre-configured Authentication
- Email/Password authentication with built-in validation
- Session management with secure cookies
- Database integration with Drizzle ORM
- Type-safe API throughout your application
Authentication Pages
/signin
- Login form with email/password/signup
- Registration form with validation/dashboard
- Protected route example
API Routes
/api/auth/[...all]
- Handles all authentication endpoints- Session management built into the API layer
Authentication Flow
User Registration
import { auth } from "~/lib/auth";
const { data, error } = await auth.api.signUpEmail({
body: {
name: "John Doe",
email: "[email protected]",
password: "securePassword123",
},
});
User Login
import { auth } from "~/lib/auth";
const { data, error } = await auth.api.signInEmail({
body: {
email: "[email protected]",
password: "securePassword123",
},
});
Note: See how we're using the
auth.api
methods to handle user login / signup? The better-auth api provides server-side access to authentication methods, meaning Next.js can handle this securely without exposing sensitive logic to the client.
Working with Sessions
Server Components
// app/dashboard/page.tsx
import { auth } from "~/lib/auth";
import { headers } from "next/headers";
import { redirect } from "next/navigation";
export default async function Dashboard() {
const headersList = await headers();
const session = await auth.api.getSession({
headers: headersList,
});
if (!session) {
redirect("/signin");
}
return (
<div>
<h1>Welcome, {session.user.name}!</h1>
<p>Email: {session.user.email}</p>
</div>
);
}
Client Components
// Client-side session handling
"use client";
import { auth } from "~/lib/auth";
export function UserProfile() {
const { data: session } = auth.getSession();
if (!session) return <div>Please sign in</div>;
return (
<div>
<h2>{session.user.name}</h2>
<p>{session.user.email}</p>
</div>
);
}
Middleware Protection
The included middleware protects routes automatically:
// middleware.ts
export const config = {
matcher: ["/dashboard"], // Protected routes are specified here
};
Custom Authentication Providers
Better Auth supports many providers. Add them in src/lib/auth.ts
.
As an example, here's how to add GitHub authentication:
First, create a GitHub OAuth app via the GitHub Developer Portal.
Next, add your GitHub client ID and secret to your environment variables:
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
Once that's included, update your src/lib/env.ts
to include the GitHub provider:
// src/lib/env.ts
const EnvSchema = z.object({
// ... existing variables
GITHUB_CLIENT_ID: z.string(),
GITHUB_CLIENT_SECRET: z.string(),
});
Now, update your src/lib/auth.ts
to include the GitHub provider:
import { betterAuth } from "better-auth";
import { env } from "~/lib/env";
export const auth = betterAuth({
// ... existing config
socialProviders: {
github: {
clientId: env.GITHUB_CLIENT_ID as string,
clientSecret: env.GITHUB_CLIENT_SECRET as string,
},
},
});
That's it! Your application now supports GitHub authentication. Signing in with a social provider is incredibly similar to email/password authentication:
import { auth } from "~/lib/auth";
const { data, error } = await auth.api.signInSocial({
body: {
provider: "github", // or any other provider you've configured
},
});