Skip to Content
Delmare Digital

Installation

Install payload-better-auth and Better Auth, check peer versions, and set the environment variables Better Auth needs.

Start with an existing Payload app, including its Next.js routes, admin layout, TypeScript aliases and core dependencies. Install the plugin together with Better Auth. The optional Better Auth packages are only needed for the features they provide.

Requirements

DependencyVersionNotes
payload>=3.90.0 <4
@payloadcms/next>=3.90.0 <4
@payloadcms/ui>=3.90.0 <4
better-auth>=1.7.7 <21.7.7 fixes a critical Magic Link account takeover. 1.6 is not supported.
next>=16.4.1 <17
react>=19.2.1 <20
@better-auth/api-key>=1.7.7 <2Optional. Only for API keys.
@better-auth/passkey>=1.7.7 <2Optional. Only for passkeys.
Node>=22.23.4Node 20 is end-of-life and unpatched.

These floors exist for security fixes in each peer. The reasons are listed under 0.14. For Payload 4 beta, see Payload 4.

Install

npm i @delmaredigital/payload-better-auth better-auth @payloadcms/db-postgres

Optional plugins. Install only what you use:

npm i @better-auth/passkey
npm i @better-auth/api-key

drizzle-orm (pinned to 0.45.2, matching Payload 3.92.1) and qrcode.react are regular dependencies and install automatically.

Environment variables

.env
# Required: use separate, randomly generated secrets
PAYLOAD_SECRET=replace-with-a-random-secret-at-least-32-characters
BETTER_AUTH_SECRET=replace-with-another-random-secret-at-least-32-characters
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/my-app

# App origin: set this to your custom domain in production
BETTER_AUTH_URL=http://localhost:3000

# OAuth providers (if using social login)
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...

Base URL on Vercel

Use the configured app origin first, then fall back to the Vercel deployment URL or localhost:

src/lib/auth/getBaseUrl.ts
export function getBaseUrl() {
  if (process.env.BETTER_AUTH_URL) return process.env.BETTER_AUTH_URL
  if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`
  return 'http://localhost:3000'
}

On a custom domain, BETTER_AUTH_URL must win over VERCEL_URL, which identifies an individual deployment. Set it to your public origin in production; use a preview-specific value or leave it unset in previews.

The quick start passes its result to Better Auth as baseURL and trustedOrigins.

Edit this page on GitHub

On this page