SignUpModal
Self-contained sign-up modal component with close handling and built-in registration submission.
Overview
SignUpModal mirrors SignInModal but uses useSignUp for registration and can show an email verification step inside the modal instead of closing immediately. The footer always prompts existing users to sign in (signInHref / onSwitchToSignIn).
Preview
Interactive preview requires JavaScript.
Install
npx @simpleauthjs/react add modal --style minimalThe 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 modal automatically scaffolds the Google and GitHub auth files when they are missing (same as running add google-auth and add github-auth).
Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
open | boolean | Yes | — | Controls visibility. |
onClose | () => void | Yes | — | Called when the modal should close (backdrop click, close button, or success without pending verification). |
onSuccess | (result: { user: ExternalUser; needsVerification: boolean }) => void | No | undefined | Fires after a successful sign-up. |
appName | string | No | undefined | Shown in the header next to the SimpleAuth badge. When set, the title becomes Create your {appName} account. |
autoSendVerification | boolean | No | true | When verification is required, sends the verification email automatically unless set to false. |
signInHref | string | No | undefined | Footer “Sign in” link when onSwitchToSignIn is not set. |
onSwitchToSignIn | () => void | No | undefined | Footer button for sign-in; takes precedence over signInHref. |
googleRedirectUrl | string | No | undefined | When set, renders Continue with Google below the email form. |
githubRedirectUrl | string | No | undefined | When set, renders Continue with GitHub below the email form. |
Usage
"use client"
import { useState } from "react"
import { SignUpModal } from "@/components/simpleauth"
export function MarketingHeader() {
const [open, setOpen] = useState(false)
return (
<>
<button type="button" onClick={() => setOpen(true)}>
Create account
</button>
<SignUpModal
open={open}
onClose={() => setOpen(false)}
appName="Acme"
googleRedirectUrl="https://myapp.com/dashboard"
githubRedirectUrl="https://myapp.com/dashboard"
/>
</>
)
}Remove the OAuth buttons
The quickest way to ship email-only modals is to omit both googleRedirectUrl and githubRedirectUrl — the buttons then do not render. To remove OAuth from the generated file entirely, edit components/simpleauth/modals/sign-up-modal.tsx and delete (a) the GoogleButton and GithubButton import lines, (b) the googleRedirectUrl / githubRedirectUrl entries in SignUpModalProps and the component destructure, and (c) the .sa-modal-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
.sa-modal-backdrop {
position: fixed;
inset: 0;
background: rgba(17, 17, 17, 0.4);
display: flex;
align-items: center;
justify-content: center;
padding: 16px;
z-index: 50;
}
.sa-modal {
width: 100%;
max-width: 360px;
background: #ffffff;
border: 1px solid #111111;
color: #111111;
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}
.sa-modal-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 12px 16px;
border-bottom: 1px solid #111111;
}
.sa-modal-heading {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
}
.sa-modal-brand {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: #111111;
}
.sa-modal-brand svg {
width: 14px;
height: 14px;
}
.sa-modal-title {
margin: 0;
font-size: 16px;
font-weight: 600;
}
.sa-modal-close {
border: none;
background: transparent;
color: #111111;
font-size: 18px;
line-height: 1;
cursor: pointer;
padding: 4px 8px;
}
.sa-modal-body {
display: flex;
flex-direction: column;
gap: 12px;
padding: 16px;
}
.sa-modal-form {
display: flex;
flex-direction: column;
gap: 12px;
text-align: left;
}
.sa-modal-field {
display: flex;
flex-direction: column;
gap: 4px;
}
.sa-modal-label {
font-size: 14px;
color: #111111;
}
.sa-modal-input {
border: 1px solid #111111;
padding: 8px 10px;
background: #ffffff;
color: #111111;
font-size: 14px;
outline: none;
}
.sa-modal-input:focus {
outline: 2px solid #111111;
outline-offset: -2px;
}
.sa-modal-error {
color: #b00020;
font-size: 13px;
margin: 0;
}
.sa-modal-button {
border: 1px solid #111111;
background: #111111;
color: #ffffff;
padding: 8px 12px;
font-size: 14px;
cursor: pointer;
}
.sa-modal-button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.sa-modal-oauth-below {
display: flex;
flex-direction: column;
gap: 10px;
width: 100%;
}
.sa-modal-divider-below {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
color: #555555;
text-transform: lowercase;
}
.sa-modal-divider-below::before,
.sa-modal-divider-below::after {
content: "";
flex: 1;
height: 1px;
background: #111111;
opacity: 0.2;
}
/* Used by SignUpModal email verification step */
.sa-verify-prompt {
display: flex;
flex-direction: column;
gap: 10px;
width: 100%;
}
.sa-verify-prompt-title {
font-size: 16px;
font-weight: 600;
margin: 0;
color: #111111;
}
.sa-verify-prompt-body,
.sa-verify-prompt-hint {
font-size: 14px;
margin: 0;
color: #111111;
line-height: 1.45;
}
.sa-verify-prompt-hint {
font-size: 13px;
color: #444444;
}
.sa-verify-prompt-success {
font-size: 13px;
margin: 0;
color: #0d5c2e;
}
.sa-verify-prompt-error {
font-size: 13px;
margin: 0;
color: #b00020;
}
.sa-verify-prompt-button {
border: 1px solid #111111;
background: #ffffff;
color: #111111;
padding: 8px 12px;
font-size: 14px;
cursor: pointer;
align-self: flex-start;
}
.sa-verify-prompt-button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.sa-modal-footer {
margin-top: 12px;
font-size: 13px;
}
.sa-modal-footer-line {
margin: 8px 0 0;
}
.sa-modal-footer-muted {
color: #555555;
}
.sa-modal-link {
background: none;
border: none;
padding: 0;
cursor: pointer;
color: #111111;
text-decoration: underline;
font: inherit;
}
.sa-modal-link:hover {
opacity: 0.85;
}
.sa-modal-footer-plain {
font-size: 13px;
color: #555555;
}
Customisation
Owned by you
Files live at components/simpleauth/modals/sign-up-modal.tsx and components/simpleauth/styles/simpleauth-modal.css.