Phone Number
Add phone verification-code and password sign-in, recovery, and verified phone management.
The HeroUI phone-number plugin contributes a phone sign-in route, password recovery views, and a verified phone-number card for account settings.
Setup
Configure Better Auth and your SMS provider
import { betterAuth } from "better-auth"
import { phoneNumber } from "better-auth/plugins"
export const auth = betterAuth({
plugins: [
phoneNumber({
otpLength: 6,
requireVerification: true,
sendOTP: ({ phoneNumber, code }) => {
void sms.send({ to: phoneNumber, body: `Your code is ${code}` })
},
sendPasswordResetOTP: ({ phoneNumber, code }) => {
void sms.send({ to: phoneNumber, body: `Your reset code is ${code}` })
}
})
]
})Normalize phone numbers on the server, preferably to E.164. Do not log codes in production. Better Auth recommends dispatching the SMS without waiting for the provider response.
Update the schema
Use your normal Better Auth schema generation or migration flow. The user model needs nullable phoneNumber and phoneNumberVerified fields, with phoneNumber kept unique.
Add the client plugin
import { createAuthClient } from "better-auth/react"
import { phoneNumberClient } from "better-auth/client/plugins"
export const authClient = createAuthClient({
plugins: [phoneNumberClient()]
})Register the HeroUI plugin
import { AuthProvider } from "@better-auth-ui/heroui"
import { phoneNumberPlugin } from "@better-auth-ui/heroui/plugins"
<AuthProvider
authClient={authClient}
navigate={navigate}
plugins={[
phoneNumberPlugin({
signIn: true,
passwordSignIn: true,
passwordReset: true,
changePhoneNumber: true
})
]}
>
{children}
</AuthProvider>Allow the new route segments
import { viewPaths } from "@better-auth-ui/core"
import { phoneNumberPlugin } from "@better-auth-ui/heroui/plugins"
const validAuthPaths = new Set([
...Object.values(viewPaths.auth),
...Object.values(phoneNumberPlugin().viewPaths.auth)
])Flow options
| UI option | Default | Server requirement |
|---|---|---|
signIn | true | sendOTP |
passwordSignIn | false | A password credential |
passwordReset | false | sendPasswordResetOTP |
changePhoneNumber | true | sendOTP |
otpLength | 6 | Must match Better Auth otpLength |
When password sign-in reports PHONE_NUMBER_NOT_VERIFIED, the UI switches to the code step. Better Auth sends that verification code automatically.
Passwordless phone verification is not a second factor. Better Auth applies 2FA to phone number and password sign-in, but not to passwordless verification.
Enable Better Auth signUpOnVerification if an unknown verified number may create an account. Use a custom phone-number view if verification must also submit other required user fields.
Options and localization
Prop
Type
Prop
Type
The implementation uses the React phone-number mutations. See the Better Auth phone-number plugin for all server options.
Last updated on