Customize Signup and Login Prompts
Before you start
Make sure your tenant has a Custom Domain configured.
Confirm you are using Universal Login for all signup and login prompts, and ensure the Customize Login Page toggle has been disabled for Login Prompts.
Check that you have a Custom Page Template configured.
Customize Signup and Login Prompts is a feature that allows customers with Custom Domain and Custom Page Template enabled to add custom fields and content to their app’s signup and login prompts.
Use Cases
Customize Signup and Login Prompts supports two use cases: custom content and data capture.
Custom content is static content like text, links, or images placed directly on the signup and login prompts.
Data capture uses form elements dynamically added to the signup and login prompts, which is useful for collecting and validating user consent or user-produced data like surname.
Data capture is available for database connections authenticated by password . When using a passwordless connection, data capture is available when authenticating by email or SMS one-time password. Passkeys and magic links are not yet supported.
Terminology
A prompt is a specific step in a given authentication flow. Each prompt has at least one screen and, depending on tenant configuration, each supported screen has either four or six entry points, which are locations in the screen where custom code (partials) can be inserted.
The following prompts can be customized:
signup
signup-id
signup-password
login
login-id
login-password
login-passwordless
login-passwordless-sms-otp
login-passwordless-email-code
Partials support HTML, CSS, Javascript, and Liquid syntax to power conditional logic and dynamic variables. In addition, any Liquid variable that is available to the Page Template is also supported.
These entry points available when a database or passwordless connection is enabled:
form-content-start
form-content-end
form-footer-start
form-footer-end
The following entry points are available when at least one social or enterprise connection is enabled:
secondary-actions-start
secondary-actions-end
Use the Management API to Manage Partials
Partials can be a maximum of 10,000 characters and are managed by the Auth0 Management API at /v2/prompts/{prompts_name}/partials
. Every prompt must specify the Screen
when adding, updating, or deleting a partial. Below is an example call to view all existing partials for a prompt, noting that ulp-container
prefix is not required when referencing entry points in API calls.
GET /api/v2/prompts/signup-id/partials
# response
# success code: 200
# not found code: 404
body: {
"signup-id": {
"form-content-start": "<div>HTML or Liquid</div>...",
"form-content-end": "<div>HTML or Liquid</div>..."
}
}
Was this helpful?
Partials can also be managed using Auth0 CLI’s Universal Login Customize Interface by running auth0 ul customize
in your terminal.
Style and Validate Form Inputs
Customize Signup and Login Prompts offers pre-built styles and support for client-side validations for certain HTML form elements. The following elements are supported:
<input type="text">
<input type="number">
<input type="checkbox">
<input type="password">
<input type="email">
<input type="tel">
<input type="url">
<select>
<textarea>
To use pre-built input styles, wrap your form element of choice in a <div>
with the ulp-field
class. Similarly, add the ulp-error
class to the same <div>
to use pre-built error styles. If the ulp-error-info
element is present, a styled error message will also be displayed.
Client-Side Validation
The feature's client-side validation framework allows customers to validate user input using HTML attributes to execute one or more custom validation functions. Validation functions can be included directly in the Partial or included in the <head>
of the page template.
To add client-side validation to a form element:
Reference the validation function using the
data-ulp-validation-function
attribute on the<div class="ulp-error-info">
element.Declare which DOM events the validation function should be run on using the
data-ulp-validation-event-listeners
attribute on the<div class="ulp-error-info">
element, noting that validations run automatically on submission.
Pre-built styling for input fields
<div class="ulp-field">
<label for="first-name">First Name</label>
<input type="text" name="ulp-first-name" id="first-name">
<div class="ulp-error-info">
First Name is Required
</div>
</div>
Was this helpful?
Pre-built styling for select fields
<div class="ulp-field">
<label for="preferred-language">Preferred Language</label>
<select name="ulp-preferred-language" id="preferred-language">
<option></option>
<option value="english">English</option>
<option value="french">French</option>
<option value="spanish">Spanish</option>
</select>
<div class="ulp-error-info">
Please Select a Language.
</div>
</div>
Was this helpful?
Pre-built styling for text fields
<div class="ulp-field">
<label for="comments">Comments</label>
<textarea type="text" name="ulp-comments" id="comments"></textarea>
<div class="ulp-error-info">
Please provide an answer.
</div>
</div>
Was this helpful?
Pre-built styling for checkbox fields
<div class="ulp-field">
<input type="checkbox" name="ulp-terms-of-service" id="terms-of-service">
<label for="terms-of-service">
I agree to the <a href="#">Terms of Service</a>
</label>
<div class="ulp-error-info">
Please agree to the Terms of Service.
</div>
</div>
Was this helpful?
Custom HTML for date fields
<style>
input[type="date"] {
padding: 16px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 16px;
outline: none;
width: 100%;
color: rgb(101, 103, 110);
}
input[type="date"]:focus {
border-color: #007BFF;
box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
}
</style>
<script> function validateDateFunction(element, formSubmitted) {
if (!formSubmitted) {
return true;
}
if (element.value)
return !!element.value;
}
</script>
<div class='ulp-field'>
<label for='birthday' id="birthday-label">Birthday (MM/DD/YYYY)</label>
<input type='date' name='ulp-birthday' id='birthday'>
<div class='ulp-error-info' data-ulp-validation-function='validateDateFunction' data-ulp-validation-event-listeners='blur,change,input,focus'>
Please enter a valid birthday.
</div>
</div>
Was this helpful?
Client-Side Phone Number Validation
// Validation Function
<script>
function validatePhoneFunction(element, formSubmitted) {
if (!formSubmitted) {
return true;
}
return element.value.replace(/\D/g, '').length === 10;
}
</script>
// Custom Input Field including the validation error HTML
<div class="ulp-field">
<label for="ulp-field-phone">Phone Number</label>
<input type="text" name="ulp-field-phone" id="ulp-field-phone">
<div
class="ulp-error-info"
data-ulp-validation-function="validatePhoneFunction"
data-ulp-validation-event-listeners="blur,change,input,focus">
Invalid phone number
</div>
</div>
Was this helpful?
Localize Content
Partial content can be localized by defining new custom text variables using the Custom Text API. Up to thirty custom text variables can be defined per screen/language combination.
Create or Update a Custom Text Variable
The Custom Text API is available here and each variable follows a var-<name>
naming convention. Calls to the API must specify the screen when adding, updating, or deleting a custom text variable. Markdown links are supported and are converted to HTML <a>
elements before being displayed to users.
Below is an example call to add a variable for the text of a terms of service checkbox label in English and Spanish. See the Management API to learn more.
# PUT /api/v2/prompts/signup-id/custom-text/en
{
"signup": {
"var-tos": "I agree with the [Terms of Service](https://en.example.com/tos)"
}
}
# PUT /api/v2/prompts/signup-id/custom-text/es
{
"signup": {
"var-tos": "Estoy de acuerdo con los [Términos de Servicio](https://es.example.com/tos)"
}
}
Was this helpful?
Use a Custom Text Variable in a Partial
Custom text variables are referenced in partials using the prompts.screen.text
object; the reference for the var-tos
example in the previous section is prompt.screen.texts.varTos
. See below for an example of how to use a previously created variable in a partial on the Signup ID Prompt, noting that the Management API's var-tos
variable is referenced as varTos
in the partial.
# PUT api/v2/prompts/signup/partials
{
"signup": {
"form-content-end": "<div class='ulp-field'><input type='checkbox' name='ulp-terms-of-service' id='terms-of-service'><label for='terms-of-service'>{{ prompt.screen.texts.varTos }}</label></div>"
}
}
Was this helpful?
Validate and Save Captured Data
Data captured by custom form elements is available in Actions, and Auth0 recommends that the collected data be validated.
Each Action receives the captured data as an object on the event.request.body
. Customers can return a validation error by using the api.validation.error
function.
When using a database connection:
Data from the Signup Prompts is accessible on the Pre User Registration trigger, and if a validation error is returned, the user is prevented from registering.
Data from Login Prompts is accessible on the Post Login trigger, and if a validation error is returned, the validation error is forwarded to the customer’s application error page.
When using a Passwordless connection:
Data from both the Signup and Login Prompts is accessible on the Post Login trigger, and if a validation error is returned, the validation error is forwarded to the customer’s application error page.
Save to User Metadata
From the Action, captured data can be sent to an external API for validation and storage or saved in user_metadata
on the user via api.user.setUserMetadata
.
# Given this code in the signup form
# <div class="ulp-field">
# <label for="full-name">Full Name</label>
# <input type="text" name="ulp-full-name" id="full-name">
# </div>
exports.onExecutePreUserRegistration = async (event, api) => {
const fullName = event.request.body['ulp-full-name'];
if(!fullName) {
api.validation.error("invalid_payload", "Missing Name");
return;
}
api.user.setUserMetadata("fullName", fullName);
};
Was this helpful?