auth pattern
Sign up
Account creation. Single screen, minimum fields, social options first.
When to use it
A new user lands and needs to create credentials. Never use this for inviting existing org members.
- Account created in under 30 seconds
- Friction below 4 visible fields
- Social options are visually equal to email
Layout regions
- header
- card
- footer
States
- default
- loading
- error
- success
Example
Next.js App Router — React Hook Form + Zod, server action submit
'use client'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { authClient } from '@/lib/auth-client'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
import { toast } from 'sonner'
const schema = z.object({
email: z.string().email('Enter a valid email'),
password: z.string().min(8, 'Use at least 8 characters'),
})
export default function SignUpPage() {
const router = useRouter()
const [submitting, setSubmitting] = useState(false)
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(schema),
})
const onSubmit = handleSubmit(async (values) => {
setSubmitting(true)
try {
const res = await authClient.signUp.email(values)
if (res.error) { toast.error(res.error.message); return }
router.push('/verify-email-sent')
} finally { setSubmitting(false) }
})
return (
<Card className="mx-auto max-w-md">
<CardHeader>
<CardTitle>Create your account</CardTitle>
<CardDescription>$29 / month, cancel any time.</CardDescription>
</CardHeader>
<CardContent>
<Stack size="3">
<Button variant="outline" onClick={() => authClient.signIn.social({ provider: 'github' })}>
<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')} />
</Field>
<Field label="Password" error={errors.password?.message}>
<PasswordInput autoComplete="new-password" {...register('password')} />
</Field>
<Button type="submit" loading={submitting}>Create account</Button>
</form>
</Stack>
</CardContent>
<CardFooter className="text-sm text-label-secondary">
Already have an account? <Link href="/sign-in">Sign in</Link>
</CardFooter>
</Card>
)
}The full Sign up pattern specifies 5 exact microcopy strings, 3 motion specs, 6 composition rules, 2 more code examples — all gated behind the full recipe. Get the full recipe.