Skip to main content

Customize the sign up form

Customize the sign up form by adding new fields or modifying existing ones.

Before you start

The next instructions assume that you have a working application that uses SuperTokens for authentication. If not, please refer to the quickstart guide and then return here.

What type of UI are you using?

Add extra fields

To include more fields in the sign up form, you need to first update both the frontend and backend configuration. Then, when the sing up payload arrives on the backend, you should add a way to persist those values.

1. Add the new fields to the UI

import SuperTokens from "supertokens-auth-react";
import EmailPassword from "supertokens-auth-react/recipe/emailpassword";
import Session from "supertokens-auth-react/recipe/session";

SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
EmailPassword.init({
signInAndUpFeature: {
signUpForm: {
formFields: [{
id: "name",
label: "Full name",
placeholder: "First name and last name"
}, {
id: "age",
label: "Your age",
placeholder: "How old are you?",
}, {
id: "country",
label: "Your country",
placeholder: "Where do you live?",
optional: true
}]
}
}
}),
Session.init()
]
});

Create custom components

By default, the new fields use input elements. To enable more complex fields you can create your own custom components.

important

You may need to disable the Shadow DOM if you're integrating with a different component library that requires you to import its own CSS. For instance, some component libraries, such as react-international-phone, might expect you to include their CSS alongside their components. For more information, refer to Disable use of shadow DOM.

Set the inputComponent property for each field that you want to customize.

import SuperTokens from "supertokens-auth-react";
import EmailPassword from "supertokens-auth-react/recipe/emailpassword"
import Session from "supertokens-auth-react/recipe/session";

SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
EmailPassword.init({
signInAndUpFeature: {
signUpForm: {
formFields: [{
id: "select-dropdown",
label: "Select Dropdown",
inputComponent: ({ value, name, onChange }) => (
<div data-supertokens="inputContainer">
<div data-supertokens="inputWrapper ">
<select
style={{
border: "unset",
borderRadius: "6px",
height: "32px",
backgroundColor: "#fafafa",
color: "#757575",
letterSpacing: "1.2px",
fontSize: "14px",
width: "100%",
marginRight: "25px",
padding: "1px 0 1px 10px"
}}
value={value}
name={name}
onChange={(e) => onChange(e.target.value)}>
<option value="" disabled hidden>
Select an option
</option>
<option value="option 1">Option 1</option>
<option value="option 2">Option 2</option>
<option value="option 3">Option 3</option>
</select>
</div>
</div>
),
optional: true,
},
{
id: "terms",
label: "",
optional: false,
nonOptionalErrorMsg: "You must accept the terms and conditions",
inputComponent: ({ name, onChange }) => (
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "left",
marginBottom: " -12px",
}}>
<input name={name} type="checkbox" onChange={(e) => onChange(e.target.checked.toString())}></input>
<span style={{ marginLeft: 5 }}>
I agree to the{" "}
<a href="https://supertokens.com/legal/terms-and-conditions" data-supertokens="link">
Terms and Conditions
</a>
</span>
</div>
),
}]
}
}
}),
Session.init()
]
});

2. Include the extra fields in the backend configuration

Change the Backend SDK initialization call to ensure that the system processes the new fields when a new user registers.

import SuperTokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";
import Session from "supertokens-node/recipe/session";

SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
supertokens: {
connectionURI: "...",
},
recipeList: [
EmailPassword.init({
signUpFeature: {
formFields: [{
id: "name"
}, {
id: "age"
}, {
id: "country",
optional: true
}]
}
}),
Session.init({ /* ... */ })
]
});

3. Save the values after a successful sign up

Use the signUpPOST API function to process the field values and persist them.

caution

SuperTokens does not store custom form fields. You can either save them in your database or use the User Metadata feature .

import SuperTokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";
import Session from "supertokens-node/recipe/session";

SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
supertokens: {
connectionURI: "...",
},
recipeList: [
EmailPassword.init({
override: {
apis: (originalImplementation) => {
return {
...originalImplementation,
signUpPOST: async function (input) {

if (originalImplementation.signUpPOST === undefined) {
throw Error("Should never come here");
}

// First we call the original implementation of signUpPOST.
let response = await originalImplementation.signUpPOST(input);

// Post sign up response, we check if it was successful
if (response.status === "OK") {

// These are the input form fields values that the user used while signing up
let formFields = input.formFields;

}
return response;
}
}
}
}
}),
Session.init({ /* ... */ })
]
});

Customize each form field

Modify labels and placeholders

To change the labels and placeholders of the fields, update the formFields property, in the recipe configuration.

import SuperTokens from "supertokens-auth-react";
import EmailPassword from "supertokens-auth-react/recipe/emailpassword"
import Session from "supertokens-auth-react/recipe/session";

SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
EmailPassword.init({
signInAndUpFeature: {
signUpForm: {
formFields: [{
id: "email",
label: "customFieldName",
placeholder: "Custom value"
}]
}
}
}),
Session.init()
]
});

Set default values

Add a getDefaultValue option to the formFields configuration to set default values. Keep in mind that the function needs to return a string.

import SuperTokens from "supertokens-auth-react";
import EmailPassword from "supertokens-auth-react/recipe/emailpassword"
import Session from "supertokens-auth-react/recipe/session";

SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
EmailPassword.init({
signInAndUpFeature: {
signUpForm: {
formFields: [{
id: "email",
label: "Your Email",
getDefaultValue: () => "john.doe@gmail.com"
}, {
id: "name",
label: "Full name",
getDefaultValue: () => "John Doe",
}]
}
}
}),
Session.init()
]
});

Change the optional error message

When you try to submit the login form without filling in the required fields, the UI, by default, shows an error stating that the Field is not optional. To customize this message set the nonOptionalErrorMsg property to a custom string.

import SuperTokens from "supertokens-auth-react";
import EmailPassword from "supertokens-auth-react/recipe/emailpassword"
import Session from "supertokens-auth-react/recipe/session";

SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
EmailPassword.init({
signInAndUpFeature: {
signUpForm: {
formFields: [{
id: "email",
label: "Your Email",
placeholder: "Email",
nonOptionalErrorMsg: "Please add your email"
}, {
id: "name",
label: "Full name",
placeholder: "Name",
nonOptionalErrorMsg: "Full name is required",
}]
}
}
}),
Session.init()
]
});

Change the field order

To customize the order of fields in your sign up form, override the EmailPasswordSignUpForm component. Use the next example as a reference.

Do you use react-router-dom?

import React from "react";
import { SuperTokensWrapper } from "supertokens-auth-react";
import { EmailPasswordComponentsOverrideProvider } from "supertokens-auth-react/recipe/emailpassword";

function App() {
return (
<SuperTokensWrapper>
<EmailPasswordComponentsOverrideProvider
components={{
EmailPasswordSignUpForm_Override: ({ DefaultComponent, ...props }) => {
return (
<DefaultComponent
{...props}
formFields={[
props.formFields.find(({ id }) => id === 'name')!,
props.formFields.find(({ id }) => id === 'email')!,
props.formFields.find(({ id }) => id === 'password')!,
]}
/>
);
},
}}>
{/* Rest of the JSX */}
</EmailPasswordComponentsOverrideProvider>
</SuperTokensWrapper>
);
}
export default App;

Change field validators

1. Update the frontend configuration

Add a validate method to any of your formFields. The following example shows how to add age verification to the form:

import SuperTokens from "supertokens-auth-react";
import EmailPassword from "supertokens-auth-react/recipe/emailpassword";
import Session from "supertokens-auth-react/recipe/session";

SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
EmailPassword.init({
signInAndUpFeature: {
signUpForm: {
formFields: [{
id: "name",
label: "Full name",
placeholder: "First name and last name"
}, {
id: "age",
label: "Your age",
placeholder: "How old are you?",
optional: true,

/* Validation method to make sure that age is above 18 */
validate: async (value) => {
if (parseInt(value) > 18) {
return undefined; // means that there is no error
}
return "You must be over 18 to register";
}

}, {
id: "country",
label: "Your country",
placeholder: "Where do you live?",
optional: true
}]
}
}
}),
Session.init()
]
});

2. Update the backend configuration

Add validate functions to each of the form fields, in the backend SDK initialization call.

import SuperTokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";
import Session from "supertokens-node/recipe/session";

SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
supertokens: {
connectionURI: "...",
},
recipeList: [
EmailPassword.init({
signUpFeature: {
formFields: [{
id: "name"
}, {
id: "age",
/* Validation method to make sure that age >= 18 */
validate: async (value, tenantId) => {
if (parseInt(value) >= 18) {
return undefined; // means that there is no error
}
return "You must be over 18 to register";
}
}, {
id: "country",
optional: true
}]
}
}),
Session.init({
})
]
});
Multi-tenancy

Notice the tenantId argument passed into the validate function. Using that, you can define custom logic per tenant. For example, you can define different password policies for different tenants.

Change the default email and password validators

By default, SuperTokens adds an email and a password validator to the sign up form.

  • The default email validator makes sure that the provided email is in the correct email format.
  • The default password validator makes sure that the provided password:
    • has a minimum of 8 characters.
    • contains at least one lowercase character
    • contains at least one number

To add your own validators follow the steps described initially in this section.

important
  • The email validator that you define for sign up is also applied automatically to sign in.
  • The password validator that you define for sign up is also applied automatically to reset password forms.

Here is an example of what you need to change.

1. Update the frontend configuration
import SuperTokens from "supertokens-auth-react";
import EmailPassword from "supertokens-auth-react/recipe/emailpassword";

SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
EmailPassword.init({
signInAndUpFeature: {
signUpForm: {
formFields: [{
id: "email",
label: "...",
validate: async (value) => {
// Your own validation returning a string or undefined if no errors.
return "...";
}
}, {
id: "password",
label: "...",
validate: async (value) => {
// Your own validation returning a string or undefined if no errors.
return "...";
}
}]
}
}
})
]
});
1. Update the backend configuration
import SuperTokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";

SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
supertokens: {
connectionURI: "...",
},
recipeList: [
EmailPassword.init({
signUpFeature: {
formFields: [{
id: "email",
validate: async (value, tenantId) => {
// Your own validation returning a string or undefined if no errors.
return "...";
}
}, {
id: "password",
validate: async (value, tenantId) => {
// Your own validation returning a string or undefined if no errors.
return "...";
}
}]
}
}),
]
});

To add "Terms of service" and "Privacy policy" links to your sign up page add the links in the frontend SDK initialization call. Based on the provided configuration the data renders in the following way:

import SuperTokens from "supertokens-auth-react";

SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
termsOfServiceLink: "https://example.com/terms-of-service",
privacyPolicyLink: "https://example.com/privacy-policy",
recipeList: [/* ... */]
});

See also