<SignUpForm/> component
<SignUpForm /> is the embedded sign-up surface. It reads deployment auth settings, invitation state, and the current session before it decides which fields, strategies, and redirects are available.
Usage
The following example shows a basic usage of <SignUpForm />.
import { DefaultStylesProvider, SignUpForm } from '@wacht/tanstack-router';export default function SignUpFormUsage() { return ( <> <DefaultStylesProvider> <SignUpForm /> </DefaultStylesProvider> </> );}Entry and state
The component reads from useSignUp(), useDeployment(), useSession(), useNavigation(), and the OAuth sign-in helper so it can combine the signup attempt, session state, and deployment settings in one place.
It keeps local form state for names, email, username, phone number, password, country code, invitation token, OTP code, and loading flags.
The sign-up hook returns the current
signupAttempt together with discardSignupAttempt(), so the component can reset and restart the flow when the user switches methods.- The initial redirect target comes from
redirect_uri, then deployment sign-up settings, then the deployment frontend host. - In staging, the redirect keeps
__dev_session__attached so the session survives the round trip. - When the current session already contains an active sign-in, the component short-circuits unless multi-session support is enabled.
Account details
The visible fields come directly from
deployment.auth_settings. First name, last name, username, email, phone number, and password each render only when the deployment enables them.Required markers, validation, and read-only behavior follow the deployment settings too.
The field inputs are also normalized before submit: email is lowercased and phone numbers are stripped to digits and formatting characters the component can validate.
- If the invitation validator pre-fills the email address, the field becomes read-only.
- The form validates the name, username, email, phone, and password fields before it submits the request.
- The submit payload includes
phone_country_codewhen the phone field has one andinvite_tokenwhen an invitation token is present. - Name, username, email, phone, and password each have their own validation rules before the create request is allowed to go out.
Invitations and waitlist
An invitation token can come from the
invite_token query parameter, or from the surrounding page if you pass it through before rendering the component.When an invitation token is present, the component validates it and pre-fills the invited user details if the token is valid.
The invitation data can prefill first name, last name, and email, and the email field becomes read-only when the invite already fixes it.
If the deployment is in waitlist mode and there is no invite token, the component redirects to the waitlist page instead of rendering the sign-up form.
If the deployment is restricted, the form shows a restricted message and points the user toward support.
- Invitation validation uses
validateDeploymentInvitation()on the sign-up helper. - The restricted-state help link falls back to the sign-in page with
?help=true, or to/contactwhen no sign-in page is configured. - The waitlist redirect uses the configured waitlist page URL first and falls back to the deployment frontend host when that setting is missing.
Social sign-up
If the deployment exposes enabled social connections, the component renders the social buttons above the form and uses the OAuth sign-in helper to start the provider flow.
The
redirect_uri query parameter is forwarded into the OAuth request so the user returns to the same place after the provider flow completes.The social flow uses the same redirect selection as the rest of the component, so provider auth does not bypass the sign-up page’s own destination rules.
- The social button block disappears when no enabled social connections are available.
- The provider flow uses the same deployment-backed redirect behavior as the rest of the component.
- The OAuth helper returns an
oauth_url, and the component navigates there directly after the request succeeds.
Verification and completion
Submitting the form creates a sign-up attempt. If the deployment requires email or phone verification, the component switches into the OTP step instead of finishing immediately.
The verification screen reuses the same attempt and can resend the code when the user asks for it.
The OTP screen changes its labels and support copy based on whether the current step is email verification or phone verification.
- When the verification response returns an active sign-in, the component refreshes the session and proceeds with the logged-in state.
- When the attempt completes, the component resolves the final redirect using
redirect_uri, then the deployment redirect setting, then the frontend host. - The resend action uses
email_otporphone_otpdepending on the step the attempt is currently in. - If the attempt is completed and the deployment is in staging mode, the redirect keeps the stored dev session query parameter intact.
Reset and retry
The “Use other method” action clears the current form data, OTP state, and signup attempt so the user can start over from the first screen.
That reset is important when the current attempt has already moved into a verification branch and the user wants to switch strategies.
- Resetting also clears the local invitation and error state.
- The component uses the same helper path for both a clean restart and a recovery from a partial attempt.
Examples
Embedded sign-up page
import { SignUpForm } from '@wacht/tanstack-router';export default function SignUpFormEmbeddedSignUpPage() { return ( <> <SignUpForm /> </> );}Custom page shell
export default function SignUpPage() { return ( <main className="mx-auto max-w-md py-12"> <h1>Create your account</h1> <SignUpForm /> </main> );}