auth pattern

Sign in

Returning user authentication. Email + password, social, magic-link entry.

When to use it

User has an account and is returning. Fastest path to authenticated state.

  • Authenticated in under 10s
  • Social options equal weight to email
  • Forgot-password one tap away

Layout regions

  • header
  • card
  • footer

States

  • default
  • loading
  • error
  • partial
  • success

Example

Next.js with 2FA branch + redirect to dashboard

'use client'
import { useForm } from 'react-hook-form'
import { authClient } from '@/lib/auth-client'
import { useRouter, useSearchParams } from 'next/navigation'
import { useState } from 'react'

export default function SignInPage() {
  const router = useRouter()
  const search = useSearchParams()
  const next = search.get('next') ?? '/dashboard'
  const [submitting, setSubmitting] = useState(false)
  const { register, handleSubmit, formState: { errors } } = useForm()

  const onSubmit = handleSubmit(async (values) => {
    setSubmitting(true)
    try {
      const res = await authClient.signIn.email(values)
      if (res.error) { /* generic toast */ return }
      if (res.data?.twoFactorRedirect) { router.push('/verify-2fa?next=' + encodeURIComponent(next)); return }
      router.push(next)
    } finally { setSubmitting(false) }
  })

  return (
    <Card className="mx-auto max-w-md">
      <CardHeader><CardTitle>Welcome back</CardTitle></CardHeader>
      <CardContent>
        <Stack size="3">
          <Button variant="outline" onClick={() => authClient.signIn.social({ provider: 'github', callbackURL: next })}><Icon name="github" /> Continue with GitHub</Button>
          <Divider variant="with-text">or</Divider>
          <form onSubmit={onSubmit} className="flex flex-col gap-3">
            <Field label="Email" error={errors.email?.message}><Input autoComplete="email" autoFocus {...register('email', { required: true })} /></Field>
            <Field label="Password" trailing={<Link href="/forgot-password">Forgot?</Link>} error={errors.password?.message}><PasswordInput autoComplete="current-password" {...register('password', { required: true })} /></Field>
            <Button type="submit" loading={submitting}>Sign in</Button>
          </form>
        </Stack>
      </CardContent>
    </Card>
  )
}

The full Sign in pattern specifies 4 exact microcopy strings, 2 motion specs, 5 composition rules, 2 more code examples — all gated behind the full recipe. Get the full recipe.

Build the Sign in pattern in your project.