Add custom onboarding to your authentication flow
Onboarding is a crucial part of many authentication flows. Sometimes you need to make sure certain criteria is met and collected before allowing access to parts of your application. With Clerk, you can leverage customizable session tokens, public metadata, and Middleware to create a custom onboarding experience.
This guide demonstrates how to create a custom onboarding flow that requires users to complete a form before they can access the application. After a user authenticates using the Account Portal, the user is prompted to fill out a form with an application name and type. Once the user has completed the form, they are redirected to the application's homepage.
In this guide, you will learn how to:
- Add custom claims to your session token
- Configure your Middleware to read session data
- Update the user’s onboarding state
For the sake of this guide, examples are written for Next.js App Router, but can be used with Next.js Pager Router as well. The examples have been pared down to the bare minimum to enable you to easily customize them to your needs.
Add custom claims to your session token
Session tokens are JWTs that are generated by Clerk on behalf of your instance, and contain claims that allow you to store data about a user's session. With Clerk, when a session token exists for a user, it indicates that the user is authenticated, and the associated claims can be retrieved at any time.
For this guide, you will use an onboardingComplete
property in the user's public metadata to track their onboarding status. But first, you need to add a custom claim to the session token that will allow you to access the user's public metadata in your Middleware.
To edit the session token:
-
In the Clerk Dashboard, navigate to the Sessions page.
-
In the Customize session token section, select the Edit button.
-
In the modal that opens, you can add any claim to your session token that you need. For this guide, add the following:
-
Select Save.
To get auto-complete and prevent TypeScript errors when working with custom session claims, you can define a global type.
- In your application's root folder, add a
types
directory. - Inside of the
types
directory, add aglobals.d.ts
file. - Create the
CustomJwtSessionClaims
interface and declare it globally. - Add the custom claims to the
CustomJwtSessionClaims
interface.
For this guide, your globals.d.ts
file should look like this:
Configure your Middleware to read session data
clerkMiddleware()
allows you to configure access to your routes with fine grained control. It also allows you to retrieve claims directly from the session and redirect your user accordingly.
The following example demonstrates how to use clerkMiddleware()
to redirect users based on their onboarding status. If the user is signed in and has not completed onboarding, they will be redirected to the onboarding page.
Note that the following example protects all routes except one. This is so that any user visiting your application is forced to authenticate, and then forced to onboard. You can customize the array in the createRouteMatcher()
function assigned to isPublicRoute
to include any routes that should be accessible to all users, even unauthenticated ones.
Create a layout for the /onboarding
route
You will need a layout for the /onboarding
route that will redirect users to the homepage if they have already completed onboarding.
- In your
/app
directory, create an/onboarding
folder. - In your
/onboarding
directory, create alayout.tsx
file and add the following code to the file. This file could also be expanded to handle multiple steps, if multiple steps are required for an onboarding flow.
Add fallback and force redirect URLs
To ensure a smooth onboarding flow, add redirect URL's to your environment variables. The fallback redirect URL is used when there is no redirect_url
in the path. The force redirect URL will always be used after a successful sign up.
Use publicMetadata
to track user onboarding state
Each Clerk user has a User
object that contains a publicMetadata
property, which can be used to store custom data about the user. This information can be accessed on the client-side and can be used to drive application state. For more information, see the guide on metadata.
You can use the user's publicMetadata
to track the user's onboarding state. To do this, you will create:
- A process in your frontend with logic to collect and submit all the information for onboarding. In this guide, you will create a simple form.
- A method in your backend to securely update the user's
publicMetadata
Collect user onboarding information
To collect the user's onboarding information, create a form that will be displayed on the /onboarding
page. This form will collect the user's application name and application type. This is a very loose example — you can use this step to capture information from the user, sync user data to your database, have the user sign up to a course or subscription, or more.
- In your
/onboarding
directory, create apage.tsx
file. - Add the following code to the file.
Update the user's publicMetadata
in your backend
Now that there is a form to collect the user's onboarding information, you need to create a method in your backend to update the user's publicMetadata
with this information. This method will be called when the user submits the form.
- In your
/onboarding
directory, create an_actions.ts
file. - Add the following code to the file. This file includes a method that will be called on form submission and will update the user's
publicMetadata
accordingly. The following example uses theclerkClient
wrapper to interact with the Backend API and update the user'spublicMetadata
.
Wrap up
Your onboarding flow is now complete! 🎉 Users who have not onboarded yet will now land on your /onboarding
page. New users signing up or signing in to your application will have to complete the onboarding process before they can access your application. By using Clerk, you have streamlined the user authentication and onboarding process, ensuring a smooth and efficient experience for your new users.
Feedback
Last updated on