When to use it
User reviews / hardens account security.
- 2FA setup in <60s
- Active sessions visible per device
- Sign-out-everywhere CTA
Layout regions
- main
- twofa-card
- sessions-card
States
- default
- partial
- success
Example
Next.js — Better Auth twoFactor plugin, QR + manual secret + backup codes
'use client'
import { useEffect, useState } from 'react'
import QRCode from 'qrcode'
import { authClient } from '@/lib/auth-client'
export default function SecuritySettings({ user }) {
const enabled = user.twoFactorEnabled
const [setupState, setSetupState] = useState<{ totpURI: string; backupCodes: string[] } | null>(null)
const enable = async (password: string) => {
const r = await authClient.twoFactor.enable({ password, issuer: 'Brand' })
if (r.data) setSetupState(r.data)
}
return (
<Container>
<Stack size="6">
<Card>
<CardHeader>
<CardTitle>Two-factor authentication</CardTitle>
<Badge variant={enabled ? 'default' : 'muted'}>{enabled ? 'Enabled' : 'Disabled'}</Badge>
</CardHeader>
<CardContent>
{enabled
? <Stack><Button variant="outline">Regenerate backup codes</Button><Button variant="ghost" className="text-destructive">Disable 2FA</Button></Stack>
: <PasswordPromptForm onSubmit={enable} cta="Set up 2FA" />}
</CardContent>
</Card>
<SessionsCard sessions={user.sessions} />
</Stack>
<SetupDialog state={setupState} onClose={() => setSetupState(null)} />
</Container>
)
}
function QrPanel({ uri }) {
const [dataUrl, setDataUrl] = useState(null)
useEffect(() => { QRCode.toDataURL(uri, { width: 220 }).then(setDataUrl) }, [uri])
return dataUrl ? <img src={dataUrl} alt="2FA QR code" /> : <Skeleton variant="rect" className="h-[220px] w-[220px]" />
}The full Settings — security pattern specifies 4 exact microcopy strings, 1 motion spec, 4 composition rules, 2 more code examples — all gated behind the full recipe. Get the full recipe.