Before you start

You need:
By the end of this guide, you’ll have an identity-first flow with customized Login ID and Login Password screens. To learn more, read the Getting Started guide and visit the SDK reference guide.

Setup

In your , set up Universal Login, Identifier First Authentication, and a Database Connection 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/auth0-acul-react-boilerplate Install the ACUL SDK. After cloning the react boilerplate, change the directory to the auth0-acul-react-boilerplate folder and install the SDK.
# 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. 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 Identifier First Login with Password flow will use button, label, input, text, link, CardHeader, CardTitle, CardDescription, and CardContent components.
npx shadcn@latest init

npx shadcn@latest add button input label text link card

Step 1. Build the login-id screen

Below is a full sample of the Screen. This example uses Shadcn components.

Import and initialize the SDK

In the auth0-acul-react-boilerplate/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.
import { LoginId as ScreenProvider } from "@auth0/auth0-acul-js";

export default function LoginId() {
  // 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 provides properties and methods to access the data. For more information about context data, read Universal Login Context Data.
<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>
    <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.
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.loginid({ username: identifierInput?.value });
  };

Step 2. Build the login-password screen

Below is a full sample of the screen.

Import and initialize the SDK

In the auth0-acul-react-boilerplate/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.
import { LoginPassword as ScreenProvider } from "@auth0/auth0-acul-js";

export default function LoginPassword() {
  // Initialize the SDK
  const [SDK] = useState(() => 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 provides properties and methods to access the data.
<CardContent>
        <Text className="mb-4 text-large">
          <span className="inline-block">
            Log in as
            <span className="inline-block ml-1 font-bold">
              {screenProvider.screen.data?.username}.
            </span>
          </span>
          <Link
            href={screenProvider.screen.editIdentifierLink ?? "#"}
            className="ml-2"
          >
            {screenProvider.screen.texts?.editEmailText ?? "Edit Email"}
          </Link>
        </Text>
        <Input
          type="hidden"
          name="identifier"
          id="identifier"
          value={screenProvider.screen.data?.username}
        />
        <div className="mb-2 space-y-2">
          <Label htmlFor="password">
            {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.
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,
    });
  };

Step 3. Configure ACUL to use local assets

Use Auth0 CLI, Terraform, or the to enable ACUL. For details about what can be configured, read Configure ACUL Screens.

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.
# Creates the local assets 

npm run build 
cd dist 

# Serves the assets from localhost

npx serve -p 8080 --cors

Step 4: Deploy the assets and update your tenant configuration

Advanced Customization for works with all modern Javascript bundlers. like Vite and Webpack. For more information, read Deploy and Host Advanced Customizations. For more information about deploying ACUL to your tenant, read Configure ACUL Screens.
Read…To learn…                                
Advanced Customizations for Universal LoginHow Advanced Customizations work.
Getting Started with Advanced CustomizationsGetting Started basics for Advanced Customizations
Advanced Customizations for Universal Login: ScreensA list of all screens available for Advanced Customizations.