# Sign Up

> Create user accounts with email/password, magic link, or OAuth in your Next.js SaaS application with Better Auth.

*Canonical: https://makerkit.dev/docs/nextjs-prisma/authentication/sign-up*

---

New users create accounts via the sign-up form, which automatically creates a personal account, sends email verification, and establishes a session. Same auth methods as sign-in.

This page is part of the [Authentication documentation](./overview).

Sign-up creates a new user with automatic personal account provisioning in your PostgreSQL database via Prisma. Users register with email/password (default), magic link, or OAuth. Email verification is required by default: users receive a verification link and must confirm before accessing the app. Password requirements (length, special characters) are configurable via environment variables, and the form shows requirements in real-time.

Sign-up is the registration flow where new users create an account, triggering user record creation in the database, personal account provisioning, and email verification.

**Use email/password sign-up when:** you want users to create credentials you control, with configurable password requirements.

**Use OAuth sign-up when:** you want frictionless registration with existing Google, GitHub, or Apple accounts.

**If unsure:** enable both. Users choose their preferred method.

## Sign Up Page

- **Location:** `apps/web/app/[locale]/auth/sign-up/page.tsx`
- **Route:** `/auth/sign-up`

The sign-up form is at `packages/auth/src/components/sign-up-methods-container.tsx`.

## Email/Password Sign Up

The default registration method. Users enter their email, name, and password.

{% img src="/images/docs/sign-up-email-password.webp" width="2388" height="1798" /%}

Enable or disable email/password registration:

```bash {% title="./.env.local" %}
NEXT_PUBLIC_AUTH_PASSWORD=true
```

### Password Requirements

Configure password complexity rules. These apply to both registration and password changes:

```bash {% title="./.env.local" %}
NEXT_PUBLIC_PASSWORD_MIN_LENGTH=8
NEXT_PUBLIC_PASSWORD_MAX_LENGTH=99
NEXT_PUBLIC_PASSWORD_REQUIRE_SPECIAL_CHARS=true
NEXT_PUBLIC_PASSWORD_REQUIRE_NUMBERS=true
NEXT_PUBLIC_PASSWORD_REQUIRE_UPPERCASE=true
```

The form displays these requirements to users in real-time as they type. Failed requirements are highlighted.

### Terms and Conditions

Display a terms and conditions checkbox on the sign-up form:

```bash {% title="./.env.local" %}
NEXT_PUBLIC_DISPLAY_TERMS_AND_CONDITIONS_CHECKBOX=true
```

When enabled, users must check the box before registration completes.

## Email Verification

By default, users must verify their email before accessing the app. After sign-up, they receive an email with a verification link. Clicking the link confirms their address and allows sign-in.

Email verification:
- Prevents account takeover via email typos
- Confirms the user controls the email address
- Reduces fake account creation

To configure email verification behavior, see [Auth Methods](../better-auth/auth-methods).

The verification email template is at `packages/email-templates/src/emails/verification.email.tsx`.

## OAuth Sign Up

Users can register with existing accounts from Google, GitHub, Apple, and other OAuth providers. The flow is the same as OAuth sign-in: if the user doesn't exist, an account is created automatically.

```bash {% title="./.env.local" %}
NEXT_PUBLIC_AUTH_OAUTH_PROVIDERS=google,github
```

See [Social Providers](../better-auth/social-providers) for configuration.

## Magic Link Sign Up

Magic links work for both sign-in and sign-up. If a user enters an email that doesn't exist, an account is created. Enable magic links:

```bash {% title="./.env.local" %}
NEXT_PUBLIC_AUTH_MAGIC_LINK=true
```

## Passkeys

Passkeys are **not** a sign-up method. A passkey is bound to an existing account, so users first sign up with another method, then register a passkey from **Settings → Security**. See [Passkey Sign In](./sign-in) and [Auth Methods](../better-auth/auth-methods).

## What Happens After Sign-Up

1. **User record created** in the database via Prisma
2. **Personal account provisioned** automatically
3. **Verification email sent** (if enabled)
4. **Session established** and stored in the database
5. **User redirected** to verification page or dashboard

## CAPTCHA Protection

Protect registration from bots with Cloudflare Turnstile:

```bash {% title="./.env.local" %}
NEXT_PUBLIC_CAPTCHA_SITE_KEY=your-turnstile-site-key
CAPTCHA_SECRET_KEY=your-turnstile-secret-key
```

When configured, the sign-up form displays a CAPTCHA challenge.

See [Captcha Plugin](../better-auth/captcha-plugin) for complete setup.

## Common Pitfalls

- **Skipping email verification in production**: Without verification, typos create orphaned accounts and users can claim others' email addresses. Always enable verification.
- **Password requirements too strict**: Users abandon registration. 8+ characters with one number is a reasonable minimum. Don't require 16+ characters or 4 different character types.
- **Not testing the full flow**: Sign-up, verification email, click link, access app. Test the entire chain.
- **Forgetting personal account creation**: Every user gets a personal account automatically. Don't manually create accounts in onboarding.
- **OAuth users expecting password**: Users who sign up with Google don't have a password. They can add one later from settings if needed.
- **Duplicate accounts from OAuth + email**: A user signs up with Google (`user@gmail.com`), then later tries email/password signup with the same email. Better Auth handles linking, but test this flow.
- **Terms checkbox not enforced server-side**: If you require terms acceptance, validate it on the server too, not just the checkbox.

{% faq
   title="Frequently Asked Questions"
   items=[
     {"question": "Can I collect additional data during sign-up?", "answer": "The default form collects email, password, and name. For additional fields, customize the sign-up component at packages/auth/src/components/ or use a post-registration onboarding flow."},
     {"question": "How do I customize the verification email?", "answer": "Edit the template at packages/email-templates/src/emails/verification.email.tsx. It supports i18n and custom styling with React Email."},
     {"question": "Can I disable email verification?", "answer": "Yes, but not recommended for production. Email verification prevents account takeover via email typos and confirms users control their email address."},
     {"question": "What if a user does not receive the verification email?", "answer": "Check mailer configuration, spam folders, and email delivery logs. Users can request a new verification email from the sign-in page."},
     {"question": "Can existing users sign up again?", "answer": "No. If the email exists, the form shows an appropriate message. Users are directed to sign in instead."},
     {"question": "How do I add a referral code field?", "answer": "Customize the sign-up component to add the field, then store the referral code in user metadata or a separate table after registration."}
   ]
/%}

---

**Next:** [Password Reset](./password-reset) | [Session Handling](./session-handling)
