Sign-in
Phone numbers
Sign in with a code by text, sent through your own SMS provider.
Better Auth's Phone Number plugin. Texts go through your own sender, the same way emails do.
Turning it on
Enable it, and point at your sender
nuxt.config.ts
export default defineNuxtConfig({
betterAuthUi: {
phoneNumber: { enabled: true },
sms: { send: './server/sms/send.ts' }
}
})
Write the sender
Its default export delivers a text, for example with Twilio:
server/sms/send.ts
import { defineBetterAuthSmsSender } from '@treygrr/nuxt-better-auth-ui/sms'
export default defineBetterAuthSmsSender(async ({ to, text }) => {
await twilio.messages.create({ to, from: '+15550000000', body: text })
})
Run Better Auth's migrations
The plugin adds phoneNumber and phoneNumberVerified columns to the user table.
How people use it
- Sign-in page: "Text code" asks for the number, texts a code, and signs in with it. Spaces, dashes and brackets are dropped; people include their country code. Users with two-factor on are asked for their code next.
- New numbers: with
signUp, a code to a new number creates an account named after it. Without it, unknown numbers are told to sign in another way and add their number from their account. - Account page: a phone number card to add, change (verified with a code) or remove a number.
- Admin: staff see a user's number on their page.
The texts
"123456 is your App code. It expires in 5 minutes.", in the pages' language. The code comes first, so phones offer to fill it in. Texts are sent in the background, as Better Auth advises.
Your sender gets more than to and text, so it can write its own message:
| Field | What it is |
|---|---|
to | The phone number |
text | The module's message |
code | The code itself |
sms | Which text it is: phone-code (signing in, verifying a number) or phone-reset |
Options
enabled
booleandefault: false
signUp
booleandefault: false
A code to a new number creates an account. Its generated email,
<digits>@phone-number.invalid, is never emailed;
people can add a real one from their account.otpLength
numberdefault: 6
Digits in a code.
expiresIn
numberdefault: 300
Seconds a code lasts.
allowedAttempts
numberdefault: 3
Wrong tries before a code stops working.
Texts cost money, and asking for a code texts any number. The captcha guards it by
default, alongside Better Auth's rate limits: keep it on.