@delmaredigital/payload-better-auth
v0.6.9
Published
Better Auth adapter and plugins for Payload CMS
Downloads
3,921
Maintainers
Readme
@delmaredigital/payload-better-auth
Better Auth adapter and plugins for Payload CMS. Enables seamless integration between Better Auth and Payload.
Upgrading to 0.5? This release requires Better Auth 1.5 and includes breaking changes to client plugins, API key imports, and auth instance types. See the CHANGELOG for migration instructions.
Documentation
Full Documentation — API reference, guides, recipes, UI components, and more.
For AI-assisted exploration: DeepWiki
Install
pnpm add @delmaredigital/payload-better-auth better-authRequirements: payload >= 3.69.0 · better-auth >= 1.5.0 · next >= 15.4.8 · react >= 19.2.1
Quick Start
1. Auth Configuration
// src/lib/auth/config.ts
import type { BetterAuthOptions } from 'better-auth'
export const betterAuthOptions: Partial<BetterAuthOptions> = {
user: {
additionalFields: {
role: { type: 'string', defaultValue: 'user' },
},
},
emailAndPassword: { enabled: true },
}2. Users Collection
// src/collections/Users/index.ts
import type { CollectionConfig } from 'payload'
import { betterAuthStrategy } from '@delmaredigital/payload-better-auth'
export const Users: CollectionConfig = {
slug: 'users',
auth: {
disableLocalStrategy: true,
strategies: [betterAuthStrategy()],
},
access: {
read: ({ req }) => {
if (!req.user) return false
if (req.user.role === 'admin') return true
return { id: { equals: req.user.id } }
},
admin: ({ req }) => req.user?.role === 'admin',
},
fields: [
{ name: 'email', type: 'email', required: true, unique: true },
{ name: 'emailVerified', type: 'checkbox', defaultValue: false },
{ name: 'name', type: 'text' },
{ name: 'image', type: 'text' },
{
name: 'role',
type: 'select',
defaultValue: 'user',
options: [
{ label: 'User', value: 'user' },
{ label: 'Admin', value: 'admin' },
],
},
],
}3. Payload Config
// src/payload.config.ts
import { buildConfig } from 'payload'
import { postgresAdapter } from '@payloadcms/db-postgres'
import { betterAuth } from 'better-auth'
import {
betterAuthCollections,
createBetterAuthPlugin,
payloadAdapter,
} from '@delmaredigital/payload-better-auth'
import { betterAuthOptions } from './lib/auth/config'
import { Users } from './collections/Users'
import { getBaseUrl } from './lib/auth/getBaseUrl'
const baseUrl = getBaseUrl()
export default buildConfig({
collections: [Users],
plugins: [
betterAuthCollections({
betterAuthOptions,
skipCollections: ['user'],
}),
createBetterAuthPlugin({
createAuth: (payload) =>
betterAuth({
...betterAuthOptions,
database: payloadAdapter({ payloadClient: payload }),
advanced: { database: { generateId: 'serial' } },
baseURL: baseUrl,
secret: process.env.BETTER_AUTH_SECRET,
trustedOrigins: [baseUrl],
}),
}),
],
db: postgresAdapter({
pool: { connectionString: process.env.DATABASE_URL },
}),
})4. Client-Side Auth
// src/lib/auth/client.ts
'use client'
import { createPayloadAuthClient } from '@delmaredigital/payload-better-auth/client'
export const authClient = createPayloadAuthClient()
export const { useSession, signIn, signUp, signOut, twoFactor, passkey } = authClient5. Server-Side Session
import { headers } from 'next/headers'
import { getPayload } from 'payload'
import { getServerSession } from '@delmaredigital/payload-better-auth'
export default async function Dashboard() {
const payload = await getPayload({ config })
const headersList = await headers()
const session = await getServerSession(payload, headersList)
if (!session) { redirect('/login') }
return <div>Hello {session.user.name}</div>
}That's it! The plugin automatically registers auth API endpoints at /api/auth/*, injects admin UI components, and handles session management.
For MongoDB setup, API reference, customization, access control helpers, API key scopes, plugin compatibility, UI components (2FA, passkeys, password reset), recipes, and types — see the full documentation.
License
MIT
