Better Auth Lead Plugin
The `better-auth-lead` package is a plugin for the `better-auth` ecosystem, designed to extend its core functionality with lead management capabilities. It facilitates features like newsletter sign-ups, waitlists, and general lead capture by providing a dedicated database table (`leads`) and a robust API. Currently at version 0.4.0, the package is in active development, implying potential API changes in minor versions before reaching a stable 1.0 release. Key differentiators include its seamless integration with `better-auth`'s server and client infrastructure, built-in support for email verification with customizable sending logic, and the ability to define and validate lead metadata using standard schema libraries like Zod or Valibot. This allows developers to quickly add lead generation features with strong type safety and validation.
Common errors
-
table 'leads' does not exist
cause The required database migration for the `leads` table was not executed after configuring the server-side plugin.fixRun your `better-auth` migration command, typically `npx auth@latest generate`, from your project's root directory. -
TypeError: Cannot read properties of undefined (reading 'lead')
cause The `leadClient` plugin was not correctly initialized and added to the `createAuthClient` configuration on the client-side.fixVerify that `plugins: [leadClient()]` is included in your `createAuthClient` call in your client-side authentication setup file. -
400 Bad Request - INVALID_METADATA
cause The `metadata` object submitted via `authClient.lead.subscribe` or `authClient.lead.update` does not conform to the `metadata.validationSchema` defined on the server-side plugin configuration.fixAdjust the `metadata` payload on the client to match the expected structure and types defined by the server's validation schema (e.g., Zod schema).
Warnings
- breaking As a pre-1.0 package (currently 0.4.0), API surfaces and configuration options for `better-auth-lead` are subject to change without strict adherence to semantic versioning. Future minor versions (e.g., 0.5.0) may introduce breaking changes.
- gotcha The `npx auth@latest generate` command must be run after installing and configuring the `better-auth-lead` plugin on the server-side to create the necessary `leads` database table. Failing to do so will result in runtime errors related to missing database tables.
- gotcha When implementing the `sendVerificationEmail` callback, it is crucial to include robust rate-limiting and anti-spam measures. The provided example includes a basic 1-minute cooldown, but production applications should implement more sophisticated checks to prevent abuse.
- gotcha The client-side plugin `leadClient` must be imported from the specific subpath `better-auth-lead/client`. Attempting to import it directly from the package root (`better-auth-lead`) will lead to bundling issues or runtime errors indicating `leadClient` is undefined.
Install
-
npm install better-auth-lead -
yarn add better-auth-lead -
pnpm add better-auth-lead
Imports
- lead
const { lead } = require('better-auth-lead');import { lead } from 'better-auth-lead'; - leadClient
import { leadClient } from 'better-auth-lead';import { leadClient } from 'better-auth-lead/client'; - LeadMetadata
import type { LeadMetadata } from 'shared/lead-metadata-schema';
Quickstart
import { createBetterAuth } from '@better-auth/core';
import { lead } from 'better-auth-lead';
// Assume 'sendEmail' is a function that sends an email
// e.g., using nodemailer, resend, or a custom service.
async function sendEmail({ to, subject, text }: { to: string; subject: string; text: string }) {
console.log(`Sending email to ${to} with subject: ${subject}`);
console.log(`Body: ${text}`);
// In a real application, integrate with an email sending service here.
// Example: await resend.emails.send({ to, subject, text });
}
const betterAuth = createBetterAuth({
plugins: [
lead({
sendVerificationEmail: async ({ lead, url }) => {
const { verificationEmailSentAt } = lead;
// Implement basic rate-limiting to prevent sending too many emails
if (
verificationEmailSentAt &&
Date.now() - verificationEmailSentAt.getTime() < 60 * 1000 // 1 minute cooldown
) {
console.log(
`Skipping verification email for ${lead.email}: recent email already sent.`,
);
return false;
}
void sendEmail({
to: lead.email,
subject: 'Please verify your email address',
text: `Click the link to verify your email: ${url}`,
});
return true; // Indicate that an email was sent
},
onEmailVerified: async ({ lead }) => {
console.log(`Lead ${lead.email} has been successfully verified!`);
// Additional logic after email verification, e.g., update CRM, send welcome email
}
}),
],
});
// To use betterAuth, you would typically export it or integrate it into an HTTP server setup.
// For example, in a Next.js API route or an Express app.
// console.log('Better Auth with Lead plugin configured.');