> ## Documentation Index
> Fetch the complete documentation index at: https://docs-staging-quickstart-revamp.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Guide to implement ACUL for the simple Login flow

# Build Login with Password

<Card title="Before you start">
  You need:

  * An Auth0 development tenant with Universal Login configured.
  * A custom-domain-configured application.
  * A development app or a sample app (like the [React sample app](/docs/quickstart/spa/react)) running on your localhost
  * A database connection that uses passwords.
</Card>

By the end of this guide, you'll have an identity-first flow with a customized Login screen. To learn more, read the [Getting Started guide](/docs/customize/login-pages/advanced-customizations/getting-started) and visit the [SDK reference guide](/docs/customize/login-pages/advanced-customizations/getting-started/sdk-quickstart).

## Setup

In your <Tooltip tip="Auth0 Dashboard: Auth0's main product to configure your services." cta="View Glossary" href="/docs/glossary?term=Auth0+Dashboard">Auth0 Dashboard</Tooltip>, set up [Universal Login](/docs/authenticate/login/auth0-universal-login/universal-login-vs-classic-login/universal-experience), [Identifier First Authentication](/docs/authenticate/login/auth0-universal-login/identifier-first), and a [Database Connection](/docs/get-started/applications/set-up-database-connections) that uses passwords.

Run a single-page application to build custom login screens. To understand the context for Advanced Customizations interfaces, clone our boilerplate app: `git clone https://github.com/auth0-samples/auth0-acul-samples`

Install the [ACUL SDK](/docs/customize/login-pages/advanced-customizations/getting-started/sdk-quickstart). After cloning the react boilerplate, change the directory to the `auth0-acul-samples` folder and install the SDK.

```bash lines
# Clone the ACUL sample application into the root folder of your project

git clone https://github.com/auth0-samples/auth0-acul-samples.git

# Change directory to install the ACUL sample application 

cd auth0-acul-samples && npm i
```

This example uses [Shadcn components](https://ui.shadcn.com/docs/installation/vite#edit-tsconfigjson-file). Run the `shadcn` init command to set up your project. After answering a few questions to configure `components.json`, begin adding components to your project. Your completed Build Login with Password flow will use `button`, `label`, `input`, `text`, `link`, `CardHeader`, `CardTitle`, `CardDescription`, and `CardContent` components.

```bash lines
npx shadcn@latest init

npx shadcn@latest add button input label text link card
```

## Step 1. Build the login screen

<Frame>
  <img src="https://mintcdn.com/docs-staging-quickstart-revamp/jp6vZz7DhptSlPIu/images/cdy7uua7fh8z/7cQxliJ8QwGH8ESjcWTsps/758328e749385c8e54112079cadc3f0e/Screenshot_2025-02-04_at_10.14.34_AM.png?fit=max&auto=format&n=jp6vZz7DhptSlPIu&q=85&s=f43b626d0607d0b8bd1918ecc79fe160" alt="Login screen on Universal Login" width="415" height="759" data-path="images/cdy7uua7fh8z/7cQxliJ8QwGH8ESjcWTsps/758328e749385c8e54112079cadc3f0e/Screenshot_2025-02-04_at_10.14.34_AM.png" />
</Frame>

Below is a full sample of the Screen.

<Accordion title="Login">
  ```jsx lines expandable
  import { ChangeEvent } from "react";
  import { Login as ScreenProvider } from "@auth0/auth0-acul-js";

  // UI Components
  import { Label } from "@/components/ui/label";
  import { Input } from "@/components/ui/input";
  import { Button } from "@/components/ui/button";
  import { Text } from "@/components/ui/text";
  import { Link } from "@/components/ui/link";
  import {
    CardHeader,
    CardTitle,
    CardDescription,
    CardContent,
  } from "@/components/ui/card";

  export default function Login() {
    // Initialize the SDK for this screen
    const screenProvider = new ScreenProvider();

    // Handle the submit action
    const formSubmitHandler = (event: ChangeEvent<HTMLFormElement>) => {
      event.preventDefault();

      // grab the values from the form
      const identifierInput = event.target.querySelector(
        "input#identifier"
      ) as HTMLInputElement;
      const passwordInput = event.target.querySelector(
        "input#password"
      ) as HTMLInputElement;

      // Call the SDK
      screenProvider.login({
        username: identifierInput?.value,
        password: passwordInput?.value,
      });
    };

    // Render the form
    return (
      <form noValidate onSubmit={formSubmitHandler}>
        <CardHeader>
          <CardTitle className="mb-2 text-3xl font-medium text-center">
            {screenProvider.screen.texts?.title ?? "Welcome"}
          </CardTitle>
          <CardDescription className="mb-8 text-center">
            {screenProvider.screen.texts?.description ?? "Login to continue"}
          </CardDescription>
        </CardHeader>
        <CardContent>
          <div className="mb-2 space-y-2">
            <Label htmlFor="identifier">
              {screenProvider.screen.texts?.emailPlaceholder ??
                "Enter your email"}
            </Label>
            <Input
              type="text"
              id="identifier"
              name="identifier"
              defaultValue={
                screenProvider.screen.data?.username ??
                screenProvider.untrustedData.submittedFormData?.username
              }
            />
          </div>
          <div className="mb-2 space-y-2">
            <Label htmlFor="identifier">
              {screenProvider.screen.texts?.passwordPlaceholder ?? "Password"}
            </Label>
            <Input type="password" id="password" name="password" />
          </div>
          <Button type="submit" className="w-full">
            {screenProvider.screen.texts?.buttonText ?? "Continue"}
          </Button>
          <Text className="mb-2">
            {screenProvider.screen.texts?.footerText ?? "Don't have an account yet?"}
            <Link className="ml-1" href={screenProvider.screen.signupLink ?? "#"}>
              {screenProvider.screen.texts?.footerLinkText ?? "Create your account"}
            </Link>
          </Text>
          <Text>
            Need Help?
            <Link className="ml-1" href={screenProvider.screen.resetPasswordLink ?? "#"}>
              {screenProvider.screen.texts?.forgottenPasswordText ?? "Forgot your Password?"}
            </Link>
          </Text>
        </CardContent>
      </form>
    );
  }
  ```
</Accordion>

### Import and initialize the SDK

In the `auth0-acul-samples/src` folder, create a folder called `screens` and a file called `Login.tsx`. Import the SDK and in the React component initialize the SDK for the screen.

```jsx lines
import { Login as ScreenProvider } from "@auth0/auth0-acul-js";

export default function Login() {
  // Initialize the SDK for this screen
  const screenProvider = new ScreenProvider();
  ...
 }
```

### Use the SDK to access properties and methods on the screen

Using the SDK you can access the properties and methods of the screen. The [Auth0 ACUL JS SDK](/docs/customize/login-pages/advanced-customizations/getting-started/sdk-quickstart) provides properties and methods to access the data.

```jsx lines expandable
<form noValidate onSubmit={formSubmitHandler}>
      ...
      <CardContent>
        <div className="mb-2 space-y-2">
          <Label htmlFor="identifier">
            {screenProvider.screen.texts?.emailPlaceholder ??
              "Enter your email"}
          </Label>
          <Input
            type="text"
            id="identifier"
            name="identifier"
            defaultValue={
              screenProvider.screen.data?.username ??
              screenProvider.untrustedData.submittedFormData?.username
            }
          />
        </div>
        <div className="mb-2 space-y-2">
          <Label htmlFor="identifier">
            {screenProvider.screen.texts?.passwordPlaceholder ?? "Password"}
          </Label>
          <Input type="password" id="password" name="password" />
        </div>
        <Button type="submit" className="w-full">
          {screenProvider.screen.texts?.buttonText ?? "Continue"}
        </Button>
      ...
      </CardContent>
    </form>
  );
}
```

### Call the submit action

Using the SDK, submit the data captured in the screen to the server. The server process this data and will route the user to the next step in the flow. If there are errors, this screen is reloaded, allowing you to display them to the user. Errors are accessed from the SDK.

```javascript lines
const formSubmitHandler = (event: ChangeEvent<HTMLFormElement>) => {
    event.preventDefault();

    // grab the value from the form
    const identifierInput = event.target.querySelector(
      "input#identifier"
    ) as HTMLInputElement;

    // Call the SDK
    screenProvider.login({ username: identifierInput?.value });
  };
```

## Step 2: Configure ACUL to use local assets

Use Auth0 CLI, Terraform, or the <Tooltip tip="Management API: A product to allow customers to perform administrative tasks." cta="View Glossary" href="/docs/glossary?term=Management+API">Management API</Tooltip> to enable ACUL. For details about what can be configured, read [Configure ACUL Screens](/docs/customize/login-pages/advanced-customizations/getting-started/configure-acul-screens).

<Tabs>
  <Tab title="Auth0 CLI (Recommended)">
    In the root directory of your project, create a `settings` folder and include in it a `{SCREENNAME}.json` file.

    ```javascript lines expandable
    //settings.json
    {
      "rendering_mode": "advanced",
      "context_configuration": [
        "screen.texts"
      ],
      "head_tags": [
        {
          "attributes": {
            "async": true,
            "defer": true,
            "integrity": [
              "ASSET_SHA"
            ],
            "src": "http://127.0.0.1:8080/index.js"
          },
          "tag": "script"
        },
        {
          "attributes": {
            "href": "http://127.0.0.1:8080/index.css",
            "rel": "stylesheet"
          },
          "tag": "link"
        }
      ]
    }
    ```

     Enable ACUL with Auth0 CLI:

    ```bash wrap lines
    auth0 ul customize --rendering-mode advanced --prompt {SCREENNAME} --screen {SCREENNAME} --settings-file ./settings/{SCREENNAME}.json
    ```
  </Tab>

  <Tab title="Auth0 Terraform">
    In the root directory of your project, create a `login-id.json` file:

    ```javascript lines expandable
    //login-id.json
    {
      "rendering_mode": "advanced",
      "context_configuration": [
        "screen.texts"
      ],
      "head_tags": [
        {
          "attributes": {
            "async": true,
            "defer": true,
            "integrity": [
              "ASSET_SHA"
            ],
            "src": "http://127.0.0.1:8080/index.js"
          },
          "tag": "script"
        },
        {
          "attributes": {
            "href": "http://127.0.0.1:8080/index.css",
            "rel": "stylesheet"
          },
          "tag": "link"
        }
      ]
    }
    ```

     Enable ACUL with Auth0 Terraform

    ```yaml lines
    prompts:
      identifier_first: true
      universal_login_experience: classic
            mfa-login-options:
              pageTitle: 'Log in to ${clientName}'
              authenticatorNamesSMS: 'SMS'
      screenRenderers:
        - login-id:
            login-id: ./prompts/screenRenderSettings/login-id.json
    ```
  </Tab>

  <Tab title="Auth0 Management API">
    You can use Auth0 Management API to enable ACUL

    ```bash lines expandable
    curl --location --request PATCH 'https://{YOUR-CUSTOM-DOMAIN}/api/v2/prompts/{YOUR-PROMPT}/screen/{YOUR-SCREEN}/rendering' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <API TOKEN>' \
    --data '{
        "rendering_mode": "advanced",
            "context_configuration": [
            "branding.settings",
            "organization.branding",
            "screen.texts",
            "tenant.name",
            "tenant.friendly_name",
            "tenant.enabled_locales",
            "untrusted_data.submitted_form_data",
            "untrusted_data.authorization_params.ui_locales",
            "untrusted_data.authorization_params.login_hint",
            "untrusted_data.authorization_params.screen_hint"
        ],
        "head_tags": [
          {
            "tag": "script",
            "attributes": {
              "src": "http://127.0.0.1:8080/index.js",
              "defer": true
            }
          },
          {
            "tag": "link",
            "attributes": {
              "rel": "stylesheet",
              "href": "http://127.0.0.1:8080/index.css"
            }
          },
          {
            "tag": "meta",
            "attributes": {
              "name": "viewport",
              "content": "width=device-width, initial-scale=1"
            }
          }
        ]
    }'
    ```
  </Tab>
</Tabs>

### Test your configuration on a local server

ACUL requires assets to be hosted on a public URL. Run a local server and test your assets before deploying them.

```javascript lines
// Creates the local assets 

npm run build 
cd dist 

// Serves the assets from localhost

npx serve -p 8080 --cors
```

## Step 3: Deploy the assets and update your tenant configuration

Advanced Customization for <Tooltip tip="Universal Login: Your application redirects to Universal Login, hosted on Auth0's Authorization Server, to verify a user's identity." cta="View Glossary" href="/docs/glossary?term=Universal+Login">Universal Login</Tooltip> works with all modern Javascript bundlers. like Vite and Webpack. For more information, read [Deploy and Host Advanced Customizations](/docs/customize/login-pages/advanced-customizations/getting-started/deploy-and-host-advanced-customizations).

For more information about deploying ACUL to your tenant, read [Configure ACUL Screens.](/docs/customize/login-pages/advanced-customizations/getting-started/configure-acul-screens)

## Related content

<table class="table">
  <thead>
    <tr>
      <th><strong>Read...</strong></th>
      <th><strong>To learn...</strong>                                </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><a href="/docs/customize/login-pages/advanced-customizations">Advanced Customizations for Universal Login</a></td>
      <td>How Advanced Customizations work.</td>
    </tr>

    <tr>
      <td><a href="/docs/customize/login-pages/advanced-customizations/getting-started">Getting Started with Advanced Customizations</a></td>
      <td>Getting Started basics for Advanced Customizations</td>
    </tr>

    <tr>
      <td><a href="/docs/customize/login-pages/advanced-customizations/reference">Advanced Customizations for Universal Login: Screens</a></td>
      <td>A list of all screens available for Advanced Customizations.</td>
    </tr>
  </tbody>
</table>
