Email Verification
Email verification ensures users own the email addresses they sign up with. This is critical for account recovery, preventing spam, and building trust.
Enable Email Verification
export const auth = betterAuth({
emailAndPassword: {
enabled: true,
requireEmailVerification: true,
},
emailVerification: {
sendOnSignUp: true,
autoSignInAfterVerification: true,
sendVerificationEmail: async ({ user, url, token }) => {
await sendEmail({
to: user.email,
subject: "Verify your email",
html: `<a href="${url}">Click here to verify your email</a>`,
});
},
},
});How It Works
- User signs up with email and password
- Better Auth generates a verification token
- Your
sendVerificationEmailfunction sends the email - User clicks the link, which hits
/api/auth/verify-email?token=... - Better Auth verifies the token and marks the email as verified
- User is optionally auto-signed in
Sign Up → Generate Token → Send Email → User Clicks → Verify → DoneConfiguration Options
| Option | Type | Default | Description |
|---|---|---|---|
sendOnSignUp | boolean | true | Send verification email on sign up |
autoSignInAfterVerification | boolean | false | Auto sign-in after verification |
expiresIn | number | 3600 | Token expiry in seconds (1 hour) |
Custom Email Templates
With React Email
import { render } from "@react-email/render";
import { VerificationEmail } from "./emails/verification";
export const auth = betterAuth({
emailVerification: {
sendVerificationEmail: async ({ user, url }) => {
const html = render(<VerificationEmail name={user.name} verificationUrl={url} />);
await resend.emails.send({
from: "noreply@yourapp.com",
to: user.email,
subject: "Verify your email address",
html,
});
},
},
});With Resend
import { Resend } from "resend";
const resend = new Resend(process.env.RESEND_API_KEY);
export const auth = betterAuth({
emailVerification: {
sendVerificationEmail: async ({ user, url }) => {
await resend.emails.send({
from: "Your App <noreply@yourapp.com>",
to: user.email,
subject: "Verify your email",
html: `
<h1>Welcome!</h1>
<p>Click the link below to verify your email:</p>
<a href="${url}">Verify Email</a>
<p>This link expires in 1 hour.</p>
`,
});
},
},
});Resend Verification Email
Allow users to request a new verification email:
import { authClient } from "@/lib/auth-client";
async function resendVerification() {
await authClient.sendVerificationEmail({
email: "user@example.com",
callbackURL: "/dashboard",
});
}Check Verification Status
const session = await auth.api.getSession({ headers });
if (!session.user.emailVerified) {
// Redirect to verification page
}Always use a reputable email service (Resend, SendGrid, AWS SES) in production. Sending from localhost will likely land in spam folders.