Personalize And Protect the UX With Auth0 Forms
Published on March 21, 2025Your users enjoy learning on our platform, but with the vast array of content they aren't always sure what to watch when they log in. In order to help your users not feel overwhelmed when they look at the catalog, the team has decided to recommend courses based on the user’s current experience level.
For that, the team decided to capture additional user information during the login flow, also known as progressive profiling. Instead of developing everything from scratch, the team will implement such functionality directly with Auth0 using Forms, a new feature that allows the team to build the new forms with ease, reducing the amount of code and time to implementation.
Why Use This Technology?
Progressive profiling is collecting additional information about your users as they use your application. You can gather detailed user information only when relevant to a user's activities.
You could get the user's name, email, and password during sign up. Then next they login and get their company name and job title. Progressive profiling improves your users' experience by shortening the registration form and avoiding repetitive questions.
Every time a user authenticates through Auth0, Auth0 updates their user profile. You can use that data to customize the user's experience.
Auth0 Forms is a visual editor that allows you to create customizable forms to tailor your identity flows to your specific needs. With Forms you can create progressive profiling flows to decide when to prompt users to collect missing information, such as company name and job title, and store it as user_metadata
attributes.
Lab Setup
Before you get started, make sure you have all you need to run this lab:
- Complete the Identiflix Project Setup.
Create a Machine to Machine Application
Before you create an Auth0 Form, you need to be able to communicate with the Auth0 Management API to make changes to the user_metadata
. To do this, you'll need to create a new Machine to Machine application (M2M) in your Auth0 tenant.
On the Auth0 Dashboard, click Applications, then Applications on the left side. Then click Create Application.
On the Create Application modal, give your application a name and select Machine to Machine Application, then click Create
On the "Authorize Machine to Machine" modal use the drop-down to select the Auth0 Management API, this will bring up Permissions. Make sure you select the following required permissions for this lab: read:users
, update:users
, create:users
, read:users_app_metadata
,update:users_app_metadata
, create:users_app_metadata
.
After selecting them, click Authorize to save the selection.
Next step is to add the M2M application credentials to the Auth0 Forms vault.
Add Auth0 Vault Connection
The Auth0 Forms vault lets you securely store secrets or common settings. When you add a vault connection in Auth0 Forms, you can access the connection to make API calls within your flows. You'll see that in action later.
You can add a vault connection from the Auth0 Forms by going to the left side menu in your Auth0 dashboard, clicking Actions, and then Forms.
With the Forms page open, in the top left corner click top left corner, your {tenantName}
, then click Vault to open the vault page.
Now that you're on the Vault page, click Add Vault Connection. On the Add Vault Connection modal, select the Auth0 option that lets you connect to Auth0. Then click Continue
Give your vault connection a name and click Continue. The following modal will open.
In the Add Vault Connection modal, enter the connection details from the M2M application you previously created. You can access this information from the previous screen, but only if you have closed it; you can access all the required settings by going into the application's dashboard and clicking on the application's name.
Once you copy and paste those values from the application settings into the Add Vault Connection modal, click Add Vault Connection.
Create a New Auth0 Form
Now, you can create a form to prompt the user to select their experience level with Identity so the application can personalize the content based on their selection.
Open the Form editor by going to the left side menu on the Auth0 Dashboard and clicking Actions, then Forms.
Click on Create Form, then the Create Form modal will pop up. Click on Start from scratch
The form starts with three nodes already set up:
- A Start node on the left.
- A Step node in the middle.
- An Ending screen node on the right.
Set up a Step Node
A Step node is the interface that users see. You can add elements like Fields to a Step node by dragging and dropping them into the step to design the form and collect additional user information.
Drag a Rich Text text field from the Components menu to the Step node.
With the Rich Text field you can customize the text the user sees when the form is rendered. Inside the Rich text field type:
Complete your profile!
We need you to complete your profile to personalize your experience.
Or a custom message that you see fit
Click the Save button.
Now, your user needs a way to select their experience level. Grab a Choice field and drag it into the Step node.
When the Field Settings menu pops up, type in userLevel
for ID. Make sure to check the Label and Required boxes.
For Label type "What is your experience level with Identity?"
Make sure you have two options. Click the add option if you don't. Click on the first empty option and type "Beginner". Click on the second empty option and type "Intermediate".
You can further customize each option by assigning an internal value that can differ from the selection value presented to the user. For this lab, our application requires the options to be lowercase, make that change by clicking on Advanced in the options section and then clicking on Internal Values.
You can assign an internal value for each option on the Assign internal values modal. The user only sees the labels, not these values, which are used behind the scenes.
Change "Beginner" and "Intermediate" to "beginner" and "intermediate" then click Save
Configure a Flow Node
So far, our form allows us to capture user data, but we need to do something with this data. To take action and store the user's input, you'll create a Flow.
Flows are the server-side logic executed in your Forms. They can handle data collected from user inputs, among other use cases.
On the bottom of the flow editor, click Flow. This action will bring up the Flow Settings menu on the right side of the screen. On the flow settings menu, click Create New Flow
Then you will get a pop-up with a text field; enter the Flow's name. For example, I'll type "Update Experience Level". When done click Create.
In this step, you created a new Flow, by default, new Flows are empty and won't perform any actions. Click Edit Flow to open the Flow Editor in a new tab.
Similarly to designing Forms, the flow editor allows you to edit the flow's logic through a graphical interface.
You can add additional logic by clicking on the + sign in the middle of the screen. Try it now. Click the + sign.
Next, the editor will prompt you what type of action you want to perform. As you can see, there's a wide selection of default actions to choose from.
Now, select the Update User action under the Auth0 category.
Now that you're on the Update User menu, go to the Vault Connect drop-down and select the Auth0 Vault Connection you created earlier. The Auth0 Vault Connection with the correct permissions is how you connect to the Auth0 Management API to update the user metadata.
Next, on the User ID section type in a Forms variable {{context.user.user_id}}
. Variables allow you to access data contained in Forms and Flows to create custom logic. Context variables include information about the user, client, organization, transaction, and the tenant name.
Type the following code to update the user's metadata with the value selected from form fields. You can access any field value through the internal variable fields
. For example. fields.userLevel
refers to the value of our choice field.
{"user_metadata": {"userLevel": "{{fields.userLevel}}"}}
Now click Save.
Now that the Update User flow is complete click Publish in the upper right corner on the Flow editor and close out the Flows tab.
The new Flow is ready to be used, but first, you'll have to specify when it should run. For that, you can place the Flow as part of the logic by connecting nodes. All nodes in the diagram will execute in the order specified by the nodes.
Because now we only have one form in the screen, we can place the Flow logic in between the Form Step node and the End Node. To do that, simply drag the Flow node in between those two and make sure to connect the strings so that the Form connects to the Flow and the Flow connects to the End as shown in the image below.
Finally, to release our changes, click Publish
Now, the form prompts the user to choose and update their metadata based on their selection. The next step is to render the Form when a user logs in using an Auth0 Action.
Render Form with Auth0 Action
Connecting your Form to Auth0 is built into Forms, and the form editor will provide you with the Action's code you need to trigger the form during the login flow. To see instructions and access the generated code, click <>Render at the top bar of the Form editor.
This tab will show you the Post Login Auth0 Action code to display the form to the user and activate all its logic. With the given code, your form will run on each login. But, thanks to Actions, you can further customize the logic to trigger the form only under specific circumstances, for example, at the first login, when specific user metadata is missing, when new company policies are released, etc.
Because we'll customize this code further, we are only interested in the Form ID value assigned to the const FORM_ID
.
Now, you'll implement the form trigger by creating a new Post Login Auth0 Action.
Head back to your Auth dashboard, and enter the Action's Flows page by clicking Actions -> Flows on the left-side menu.
This will bring you the Actions flow editor, not to be confused with Forms flow editor that you used earlier to create the logic to save the user metadata.
The Actions flow editor uses drag-and-drop functionality, so you can place your Actions inside of the login process to run the code within your Action before the login process is complete.
In this case, the Action we create will interrupt the login before any tokens are issued and it will render your form, prompt the user for their experience level, then update the user metadata with their choice, then issue any tokens.
On the right side click the "+" and select Build from Scratch this will open the Create Action modal.
In the Name field enter "Render Experience Level", confirm the Trigger is Login / Post Login, and select the recommended Runtime. Once that's set click Create and this will open the Actions code editor where we can write to code to render the Form.
First, remove all the code in the editor and replace it with the code below. The given code validates that the user has logged in at least once before and that their experience level choice has not been set to render the form.
If the user has already stated their preference, we'll stop showing the form when logging in.
The validation uses the event
object to access information about the user, the session, and much more.
/*** @param {Event} event - Details about the user and the context in which they are logging in.* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.*/exports.onExecutePostLogin = async (event, api) => {const FORM_ID = "REPLACE_WITH_YOUR_FORM_ID";if (event.stats.logins_count > 2 && !event.user.user_metadata.userLevel) {api.prompt.render(FORM_ID);}};exports.onContinuePostLogin = async (event, api) => {};
Next, you want to ensure userLevel
gets saved to ID Token so the application can easily access its value. You need to add a custom claim to the ID token. You can set this up by going to the exports.onContinuePostLogin
function using the api
object to set the custom claim to the value the user selected for userLevel
using the event
object
exports.onContinuePostLogin = async (event, api) => {const namespace = `https://myapp.example.com`;api.idToken.setCustomClaim(`${namespace}/userLevel`,event.prompt.fields.userLevel,);};
Now that you have the code set up to render the form and save the form selection to the user ID Token. Click Deploy.
To return to the Post Login Drag and Drop flow editor, on the left side of the Actions editor click Back to Flow
On the right side of the Flow Editor on below Add Action click Custom and drag and drop the Action you just created between Start and Complete then in the upper ride side click Apply.
Now your form is a part of your login flow! The next thing you want to do is modify the code in your application to take the data from the ID Token and change the courses based on what the user selects.
Modify Application Code
If you haven't done so, open the Identiflix application's code with your favorite editor and navigate to the Page Component in the file: app/catalog/page.tsx
.
In the file, you'll find the following developer's comment and code:
// FIXME: complete the "Beyond Login: Personalize and Protect with Auth0 Forms"// lab to get the user's assigned experienceconst recommendedCourses = await DataAPI.getRecommendedCourses("beginner");
As we can see here, the course recommendations have a hardcoded value with a FIXME comment. Thanks to Auth0 forms, we can quickly fix this code and set the user's preferences instead.
To access the user's experience level, we can rely on the user object given by Auth0 SDK. This user will contain all the default attributes of the ID token, plus any custom claim we manually assigned, so to retrieve the value, we need to create a variable and assign its value as follows:
const userLevel = user["https://myapp.example.com/userLevel"] || "beginner";
We can provide a default value if the custom claim is absent. This would depend on the logic you assign to trigger your form, and how you treat the default value would depend on your application's logic.
Then, pass userLevel
as an argument to the DataAPI.getRecommendedCourses
function.
const recommendedCourses = await DataAPI.getRecommendedCourses(userLevel);
You can also delete or comment out the <Alert />
component in the return
Now run the application and log in a user after entering the username and password. If the user has more than 2 logins, they will be prompted with your form to select their experience level.
Then when you're on the homepage click Catalog and now there will be a component under Recommended Courses
depending on what the user selected.
Wrap Up
Congrats! You just improved your user experience by adding a way to collect a user's choice and show them content based on that choice.
In this lab, you added progressive profiling to your login process. Now when your users login to Identiflix they won't be presented with all the same content. In summary, you learned how to:
- Create an Auth0 Form from scratch
- Create a Forms vault connection
- Using Auth0 Actions to Render the Form you created
- Add Custom Claims to the Auth0 ID Token
Try out more features with Auth0 Forms, there are templates and 3rd party integrations you can use to add custom features to your apps.
To learn more about Auth0 Forms and extensibility check out the following sessions:
- Auth0 Forms and the Future of Extensibility in Customer Identity by Sofia Prosper
- Crafting Delightful Experiences with Advanced Customizations for Universal Login by Michael Swanson
- Call to Action! How to Use Actions Online Fast copy by Ramona Schwering
- Actions Cookbook: Practical Recipes for Your Auth Needs by Rita Zerrizuela