You can make Auth0’s Universal Login page look and behave however you want, but the most surprising thing is how much of it is not JavaScript.
Let’s see it in action. Imagine you want to change the logo and the primary button color. Here’s a snippet from a custom Handlebars template:
<style>
.auth0-lock__header {
background: #f05032; /* Auth0 orange */
}
.auth0-lock__header__logo {
background-image: url('https://example.com/my-custom-logo.png');
background-size: contain;
background-repeat: no-repeat;
height: 40px; /* Adjust as needed */
width: 120px; /* Adjust as needed */
}
.auth0-lock__button--primary {
background-color: #33cc33; /* A nice green */
border-color: #33cc33;
}
</style>
<div class="auth0-lock">
<div class="auth0-lock__header">
<div class="auth0-lock__header__logo"></div>
</div>
<div class="auth0-lock__body">
<!-- The rest of the login form elements will be injected here -->
</div>
</div>
This is a Handlebars template. Auth0 uses it to render the Universal Login page. You upload your custom HTML, CSS, and JavaScript to Auth0, and it injects the actual login form fields and logic into your template. This means you have full control over the surrounding structure, styling, and even add custom elements.
The problem this solves is brand consistency. You don’t want your users to land on a generic-looking login page that doesn’t match your application’s look and feel. Universal Login, when customized, provides a seamless transition for your users from your application to the authentication flow and back. It’s about trust and user experience.
Internally, Auth0’s Universal Login is a powerful, pre-built UI that handles all the complexities of authentication: social logins, username/password, multi-factor authentication (MFA), password resets, and more. When you customize it, you’re not rebuilding this engine; you’re building the car body around it. You can inject custom HTML, CSS, and JavaScript. The {{#block 'content'}} ... {{/block}} Handlebars syntax is key here – it’s where Auth0 injects the dynamic login form elements. You can place this block anywhere in your HTML.
The levers you control are the structure of the page (your HTML), the visual presentation (your CSS), and the dynamic behavior (your JavaScript). You can add custom fields, implement client-side validation before submitting to Auth0, or even create entirely new UI components that interact with Auth0’s authentication events. For instance, you can listen for authenticated events to trigger custom post-login actions within the UI.
Many people think customization is all about CSS, but you can significantly alter the flow. For example, you can use JavaScript to conditionally show or hide sections of the form based on user input or external factors. Imagine a scenario where, if a user selects "Forgot Password," you completely replace the standard password reset UI with your own custom-built modal that might include extra verification steps or branding. You’d typically achieve this by listening to Auth0’s Lock events and manipulating the DOM or calling Auth0’s Lock API methods to change the displayed view.
The next step in mastering Universal Login customization is understanding how to integrate custom API calls within your custom login flow.