Sign-in

Sign-in providers

Google, GitHub, Discord and more, game platforms, and sign-in in a popup.
The account page's security tab: passkeys, two-factor, and sign-in methods with Google, GitHub, Discord and Apple to connect

The sign-in, sign-up and account pages offer every provider in your Better Auth config:

There's nothing to turn on in the module: configure a provider in Better Auth and it appears.

server/auth.config.ts
export default defineServerAuth({
  socialProviders: {
    github: {
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!
    }
  }
})

Each provider shows with its own icon and name: Google, GitHub, Discord, Apple, Microsoft, Facebook, X, GitLab, Twitch, Roblox, Kick, Spotify, LinkedIn, Reddit, TikTok, Slack, Zoom, Epic Games and Battle.net. Others show their id.

On the account page, people connect more providers and disconnect them, but never the last way they have to sign in.

Epic Games and Battle.net

Better Auth has no helper for these, so @treygrr/nuxt-better-auth-ui/providers has Generic OAuth configs for them:

server/auth.config.ts
import { genericOAuth } from 'better-auth/plugins'
import { battleNet, epicGames } from '@treygrr/nuxt-better-auth-ui/providers'

export default defineServerAuth({
  plugins: [
    genericOAuth({
      config: [
        epicGames({ clientId: process.env.EPIC_CLIENT_ID!, clientSecret: process.env.EPIC_CLIENT_SECRET! }),
        battleNet({ clientId: process.env.BNET_CLIENT_ID!, clientSecret: process.env.BNET_CLIENT_SECRET! })
      ]
    })
  ]
})

Their redirect URLs are https://your-site/api/auth/callback/epic-games and https://your-site/api/auth/callback/battle-net. Names come from the Epic display name and the BattleTag.

The helpers follow Epic's and Blizzard's published OpenID set-up, but haven't been tried against the real services yet.

Providers without an email

Neither Epic Games nor Battle.net shares an email, and Better Auth needs one per user. So:

  1. The helpers give these accounts a placeholder email, <id>.<provider>@no-email.invalid. It's a reserved domain that's never emailed.
  2. The module sends these users to the finish-account page (/finish-account) before anything else.
  3. They add their email there, through Better Auth's change-email, which emails them a link. Opening it makes the email theirs.

The finish-account page needs user.changeEmail.enabled and verification emails in your Better Auth config.

Your own providers without an email can do the same with placeholderEmail:

server/auth.config.ts
import { placeholderEmail } from '@treygrr/nuxt-better-auth-ui/providers'

// In a Generic OAuth provider's getUserInfo:
return { id, name, email: placeholderEmail('my-provider', id), emailVerified: false }

Sign-in in a popup

With oauthPopup: true, the sign-in and sign-up pages open provider sign-ins in a popup instead of leaving the page. Someone signing in from inside a running app keeps its state: the popup closes itself and the page moves on, signed in. Where the browser blocks popups, the usual redirect happens instead.

nuxt.config.ts
export default defineNuxtConfig({
  betterAuthUi: {
    oauthPopup: true
  }
})
It's Better Auth's OAuth Popup plugin, which ships with Better Auth 1.7 but isn't in its documentation yet. The option also adds the Bearer plugin, which it pairs with. Users with two-factor on finish signing in inside the popup.

Not supported yet

  • Xbox gamertags: they need Xbox Live's own token exchange after the Microsoft sign-in.
  • Steam: it uses OpenID 2.0, which Better Auth doesn't support.