New Universal Login Page Customization

Universal Login

This document clarifies how the New Universal Login page can be customized, and provides guidance on when to use specific techniques.


A custom domain must be enabled for New Universal Login page customizations to work. This is one major difference between New and Classic Universal Login.

Two mechanisms are available for customizing the Universal Login page.

Page Templates: Provide for customizing the layout and appearance of the login page using liquid syntax and page template variables. Cascading Style Sheets (CSS) or Javascript (JS) can be used for more extensive customization (examples)
Text Prompts: Allow customizing the actual text of the login page. The Keys in the Text Prompts documentation correspond to the Keys listed in the prompts in the Page Templates documentation

Use Page Templates to change the layout of the page or implement conditional formatting. Page templates can use CSS or JS to hide certain page elements, as needed.

Use Text Prompts to customize the text displayed on the login page.

Page Templates

Page Templates for New Universal Login can only be updated via the Page Templates API.

CSS Customization

CSS can be used to make minor modifications to the login page:

Note the CSS class names are not static and customizations targeting them will fail. Class names change when the Auth0 product is updated, which is often. Customizations may work briefly but will fail without notice.

JS customization

New Universal Login does not depend on JS. It contains some JS, but the essential functions of the page don’t require it. JS script tags can be added to the page template to manipulate page elements. For example, to hide the signup link, consider the following template. Note this introduces a dependency on JS for the page to render as intended.

<!DOCTYPE html>

    {%- auth0:head -%}

<body class="_widget-auto-layout">
    {%- auth0:widget -%}
    <script type="text/javascript">
        document.addEventListener("DOMContentLoaded", function (event) {
            Element.prototype.remove = function () {
            NodeList.prototype.remove = HTMLCollection.prototype.remove = function () {
                for (var i = this.length - 1; i >= 0; i--) {
                    if (this[i] && this[i].parentElement) {
            var xpath = "//a[contains(@href,'signup')]";
            var signUpLink = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
            if (signUpLink) {


Text Prompts

A “prompt” is a specific step in the login flow. For example, MFA OTP enrollment (mfa-otp) or signing in with a username and password (login-password). A “screen” is a subset of a prompt. A prompt might have a single screen or multiple screens. The login-password prompt only has a single screen (login-password), where the mfa-otp prompt has the mfa-otp-enrollment-qr screen, and the mfa-otp-enrollment-code screen. The former is the screen for enrolling in MFA OTP with a QR code, and the latter provides a code for the user to manually enter in their authenticator app.

The list of prompts is available at:

When updating prompts via the API, the syntax is:

  "<screen>": {
    "<text_id>": "text1 in language"


`<prompt>`= a prompt from the list of prompts above
`<language>` = a language from the [list of supported languages](
`<screen>` = a screen from the prompt
`<text_id>` = the Key from the screen.  

For example, to change the `Trouble Scanning?` text on the MFA OTP QR code enrollment prompt, for users with their language set to English, send the following payload:

  "mfa-otp-enrollment-qr": {
    "codeEnrollmentText": "Click here if you cleaned your camera lens and still have trouble scanning."