Skip to Content
Delmare Digital

Magic link and email OTP

Offer "Email me a link" and "Email me a code" on the admin login, or make sign-in passwordless only.

The admin login detects Better Auth's magicLink() and emailOTP() plugins and shows "Email me a link" and "Email me a code". If your Better Auth config sets emailAndPassword.enabled: false, the password field is hidden and a passwordless method becomes the primary action.

src/payload.config.ts
// Each option defaults to 'auto' (show iff the matching plugin is installed).
// Force on/off, or hide the password field for passwordless-only sign-in:
admin: {
  login: {
    enableMagicLink: 'auto',   // requires magicLink() plugin
    enableEmailOtp: 'auto',    // requires emailOTP() plugin
    enablePassword: false,     // hide password field (passwordless-only)
    magicLinkCallbackURL: '/admin',
    enableSocial: ['google', 'github'], // opt-in; socialProviders or genericOAuth ids
  },
}

magicLinkCallbackURL is where the emailed link returns; it defaults to afterLoginPath.

The server side stays yours: configure magicLink() / emailOTP() and their email senders in your Better Auth instance, and the login options appear.

Run Better Auth 1.7.7 or later

1.7.7 fixes a critical Magic Link account takeover (GHSA-965c-763c-88jm). It affects magicLink() combined with a social or generic OAuth provider using database-stored OAuth state, which is the default with this adapter. The plugin's peer range already requires 1.7.7.

Added in 0.7.5.

Edit this page on GitHub