SimpleAuth
ReactComponents

SignUpForm

Registration form powered by useSignUp.

Overview

SignUpForm collects name (optional), email, and password, then calls useSignUp. A footer always reminds users who already have an account to sign in (pass signInHref or onSwitchToSignIn for a link or button). When the new user is not yet verified, it can show a Verify your email step with a resend action. Use onSuccess for navigation with a richer payload.

Preview

Interactive preview requires JavaScript.

Install

npx @simpleauthjs/react add sign-up --style minimal

The install snippet uses --style minimal. You can also use --style modern. Style variants compares those two in the live preview. Run npx @simpleauthjs/react add --help for every --style slug the CLI accepts.

Running add sign-up automatically scaffolds the Google and GitHub auth files when they are missing (same as running add google-auth and add github-auth).

Props

NameTypeRequiredDefaultDescription
onSuccess(result: { user: ExternalUser; needsVerification: boolean }) => voidNoundefinedCalled after signUp resolves without throwing.
appNamestringNoundefinedShown in the header next to the SimpleAuth badge. When set, the title becomes Create your {appName} account.
autoSendVerificationbooleanNotrueWhen needsVerification is true, automatically calls sendVerificationEmail before showing the prompt.
signInHrefstringNoundefinedRenders an “Already have an account? Sign in” link (used when onSwitchToSignIn is not set).
onSwitchToSignIn() => voidNoundefinedFooter button for sign-in; takes precedence over signInHref.
googleRedirectUrlstringNoundefinedWhen set, renders Continue with Google below the email form.
githubRedirectUrlstringNoundefinedWhen set, renders Continue with GitHub below the email form.

Usage

import { SignUpForm } from "@/components/simpleauth"

export default function RegisterPage() {
  return (
    <SignUpForm
      appName="Acme"
      onSuccess={({ needsVerification }) => {
        console.info("account created", { needsVerification })
      }}
    />
  )
}

With Google and GitHub (same components as GoogleButton / GithubButton):

<SignUpForm
  appName="Acme"
  googleRedirectUrl="https://myapp.com/dashboard"
  githubRedirectUrl="https://myapp.com/dashboard"
/>

Remove the OAuth buttons

The quickest way to ship email-only sign-up is to omit both googleRedirectUrl and githubRedirectUrl — the buttons then do not render. To remove OAuth from the generated file entirely, edit components/simpleauth/ui/sign-up-form.tsx and delete (a) the GoogleButton and GithubButton import lines, (b) the googleRedirectUrl / githubRedirectUrl entries in SignUpFormProps and the component destructure, and (c) the .sa-sign-up-oauth-below JSX block. You can also delete the unused feature files (for example components/simpleauth/ui/google-button.tsx, components/simpleauth/hooks/use-google-auth.ts, components/simpleauth/styles/google-button.css, and the GitHub equivalents).

Source

components/simpleauth/hooks/use-sign-up.ts
"use client"

import { useCallback, useState } from "react"
import { SimpleAuthError, type RegisterResponse } from "@simpleauthjs/core"
import { useSimpleAuthClient } from "../provider"

type SignUpInput = {
  email: string
  password: string
  name?: string
}

function getErrorMessage(error: unknown) {
  if (error instanceof SimpleAuthError) {
    return error.message
  }

  if (error instanceof Error) {
    return error.message
  }

  return "Unable to sign up."
}

export function useSignUp() {
  const auth = useSimpleAuthClient()
  const [isLoading, setIsLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [data, setData] = useState<RegisterResponse | null>(null)
  const [isSendingVerification, setIsSendingVerification] = useState(false)
  const [verificationError, setVerificationError] = useState<string | null>(null)
  const [verificationSent, setVerificationSent] = useState(false)

  const needsVerification = data?.user.emailVerified === false

  async function signUp(input: SignUpInput) {
    setIsLoading(true)
    setError(null)
    setVerificationError(null)
    setVerificationSent(false)

    try {
      const response = await auth.register(input)
      setData(response)
      return response
    } catch (requestError) {
      setData(null)
      setError(getErrorMessage(requestError))
      throw requestError
    } finally {
      setIsLoading(false)
    }
  }

  const sendVerificationEmail = useCallback(
    async (email: string) => {
      setIsSendingVerification(true)
      setVerificationError(null)
      try {
        await auth.sendVerificationEmail({ email })
        setVerificationSent(true)
      } catch (requestError) {
        setVerificationSent(false)
        setVerificationError(getErrorMessage(requestError))
        throw requestError
      } finally {
        setIsSendingVerification(false)
      }
    },
    [auth],
  )

  function reset() {
    setData(null)
    setError(null)
    setIsLoading(false)
    setIsSendingVerification(false)
    setVerificationError(null)
    setVerificationSent(false)
  }

  return {
    signUp,
    data,
    error,
    isError: Boolean(error),
    isLoading,
    reset,
    needsVerification,
    sendVerificationEmail,
    isSendingVerification,
    verificationError,
    verificationSent,
  }
}

Customisation

Owned by you

Generated files live at components/simpleauth/ui/sign-up-form.tsx and components/simpleauth/styles/sign-up-form.css.

Add honeypot fields, plug in password strength meters, or translate validation copy.

On this page