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.

Build the Sign up pattern in your project.