Sign-in

Usernames, links and codes

Usernames, sign-in links, codes by email, and guest accounts.

Each of these is one of Better Auth's own plugins. They're all off by default; turn on the ones you want and the sign-in pages show them.

nuxt.config.ts
export default defineNuxtConfig({
  betterAuthUi: {
    username: { enabled: true },
    magicLink: { enabled: true },
    emailOtp: { enabled: true },
    anonymous: { enabled: true }
  }
})
Sign-in links and codes by email are sent through the module's emails, so set emails.send first.

Usernames

Better Auth's Username plugin.

  • Sign up asks for a username: letters, numbers, _ and ., as Better Auth checks them.
  • Sign in takes "Email or username": anything with an @ signs in by email, anything else by username.
  • Usernames are case-insensitive: Pixel_42 and pixel_42 are the same account. They're shown as typed.
  • The account page lets people change it, unless it's immutable.
  • The admin shows it as @handle on the users list and each user's page.
enabled
booleandefault: false
minLength
numberdefault: 3
maxLength
numberdefault: 30
immutable
booleandefault: false
A username can be set once, then not changed.
Adds username and displayUsername columns to the user table: run Better Auth's migrations.

Better Auth's Magic Link plugin. "Email me a sign-in link" on the sign-in page asks for an email and sends a link that works once.

  • A new email gets an account with the first link (unless disableSignUp), and lands on the account page.
  • An expired or used link comes back to the sign-in page with a message.
  • Users with two-factor on are asked for their code after the link, as after a password.
enabled
booleandefault: false
expiresIn
numberdefault: 300
Seconds a link lasts.
disableSignUp
booleandefault: false
Links only sign existing users in.

The email's template is magic-link. No migration needed.

Codes by email

Better Auth's Email OTP plugin. "Email me a code" sends a 6-digit code to type in on the same page. It's handy for signing in on a device that doesn't have the email: a TV, a console, a shared computer.

  • Codes expire in 5 minutes and stop working after 3 wrong tries.
  • A new email gets an account (unless disableSignUp).
  • Users with two-factor on are asked for their two-factor code next.
enabled
booleandefault: false
otpLength
numberdefault: 6
Digits in a code.
expiresIn
numberdefault: 300
Seconds a code lasts.
allowedAttempts
numberdefault: 3
Wrong tries before a code stops working.
disableSignUp
booleandefault: false
Codes only sign existing users in.
As Better Auth documents, signing in with a code to an account whose email was never verified removes that account's password and signs out its sessions. The code proved who owns the email; the password didn't.

The email's template is email-code. Better Auth's other code endpoints (verifying an email, resetting a password) work too, and their emails are worded to match, but the pages only use sign-in codes. No migration needed.

Guest accounts

Better Auth's Anonymous plugin. "Continue as a guest" starts a real account with no email or password, so people can use your app straight away.

  • Their account page says it's a guest account, with "Create an account", "Sign in" and "Delete guest account". Email, password and security settings are hidden, and two-factor is never required of guests.
  • Keeping the account: the sign-in and sign-up pages let guests in. Signing up, or signing in any way, moves them to that account, and Better Auth deletes the guest one.
  • The admin shows a "Guest account" badge, and a "Guests" filter on the users list.
  • Security alerts are never sent to guests' generated addresses.

Moving a guest's data

Moving a guest's own data (a cart, saved items) to their new account is your app's job. Point onLinkAccount at a file whose default export is Better Auth's onLinkAccount:

export default defineNuxtConfig({
  betterAuthUi: {
    anonymous: {
      enabled: true,
      onLinkAccount: './server/auth/link-guest.ts'
    }
  }
})
enabled
booleandefault: false
onLinkAccount
string
A file whose default export moves a guest's data, relative to the project root. Nuxt aliases work too.
emailDomainName
stringdefault: 'anonymous.placeholder.invalid'
The domain of guests' generated email addresses.
disableDeleteAnonymousUser
booleandefault: false
Guests can't delete their guest account, and it's kept when they link a real one.
Adds an isAnonymous column to the user table: run Better Auth's migrations.