Skip to content

LoginForm container

The LoginForm container handles user email input and validation within the checkout process.

LoginForm configurations

The LoginForm container provides the following configuration options:

Option Type Req? Description
displayTitle (*)booleanNo Displays the container title (default value is true).
activebooleanNo Activates/deactivates the container (default value is true).
autoSyncbooleanNo Synchronizes/does not synchronize the container local state with the backend (default value is true).
displayHeadingContentbooleanNo Displays the container heading content (default value is true).
onSignInClickfunctionNo A function that handles the sign-in button click. It takes the email (string or null) as an argument.
onSignOutClickfunctionNo A function that handles the sign-out button click. It takes no arguments.
onCartSyncErrorfunctionNo A function that takes an error and the email address as arguments. It is called when the setGuestEmailOnCart() API throws an error when filling in the email address to be stored to the backend.
onValidationErrorfunctionNo A function that takes the email validated with the type of error and its message as arguments. It is called when the email form field is validated with an error (due to it's missing or has an invalid format).
slotsobjectNo Object with the content to be displayed on the LoginForm container. This slot allows setting the heading content dynamically based on the user authentication status.

(*) Properties inherited from TitleProps

These configuration options are implementing the LoginFormProps interface:

LoginFormProps interface

The LoginForm container receives an object as a parameter which implements the LoginFormProps interface with the following properties:

interface ValidationError {
email: string;
message: string;
type: 'missing' | 'invalid';
}
interface CartSyncError {
email: string;
error: Error;
}
export interface LoginFormProps extends HTMLAttributes<HTMLFormElement>, TitleProps {
active?: boolean;
autoSync?: boolean;
displayHeadingContent?: boolean;
onSignInClick?: (email: string) => void;
onSignOutClick?: () => void;
onCartSyncError?: (error: CartSyncError) => void;
onValidationError?: (error: ValidationError) => void;
slots?: {
Heading?: SlotProps<{
authenticated: boolean;
}>;
} & TitleProps['slots'];
}
  • The displayTitle (*) property inherits from the TitleProps interface to display or hide the title.
  • Set the active property to true to have the container in reactive mode (it is visible and responds to system events). If it is set to false, the container is deactivated (it does not subscribe to system events and is not rendered).
  • Set the autoSync property to true to automatically synchronize the container state changes with the backend via API calls. If it is set to false the container does not automatically synchronize its state, but still maintains local updates.
  • Set the displayHeadingContent property to true to display the heading content with the sign-in/sign-out button.
  • The onSignInClick property is a handler used to perform actions called when the sign-in button is clicked. It accepts an email as an input parameter.
  • The onSignOutClick property is a handler used to perform actions called when the sign-out button is clicked.
  • The onCartSyncError property is a handler used to perform actions called when filling in the email address and the setGuestEmailOnCart() API throws an error. It could be used as a callback in the integration layer by the merchant to show errors or perform other actions.
  • The onValidationError property is a handler used to perform actions called when the email address form field is validated with an error. It could be used as a callback in the integration layer by the merchant to show errors or perform other actions.
  • The slots property is an object containing the following properties:
    • Use the Title (*) property to render a custom title. This property is inherited from TitleProps interface.
    • The Heading property is a handler used to render a customized heading content based on the authenticated status provided by the context.

Example 1: Render with title and heading content by default

The following example renders the LoginForm container on a checkout page, which includes rendering the AuthCombine container from the user auth drop-in component in a modal for authentication:

import {
ProgressSpinner,
provider as UI,
} from '@dropins/tools/components.js';
import * as authApi from '@dropins/storefront-auth/api.js';
import AuthCombine from '@dropins/storefront-auth/containers/AuthCombine.js';
import { render as AuthProvider } from '@dropins/storefront-auth/render.js';
import LoginForm from '@dropins/storefront-checkout/containers/LoginForm.js';
import { render as CheckoutProvider } from '@dropins/storefront-checkout/render.js';
import { authPrivacyPolicyConsentSlot } from '../../scripts/constants.js';
const LOGIN_FORM_NAME = 'login-form';
const $loader = checkoutFragment.querySelector('.checkout__loader');
const $login = checkoutFragment.querySelector('.checkout__login');
let loader;
const displayOverlaySpinner = async () => {
if (loader) return;
loader = await UI.render(ProgressSpinner, {
className: '.checkout__overlay-spinner',
})($loader);
};
CheckoutProvider.render(LoginForm, {
name: LOGIN_FORM_NAME,
onSignInClick: async (initialEmailValue) => {
const signInForm = document.createElement('div');
AuthProvider.render(AuthCombine, {
signInFormConfig: {
renderSignUpLink: true,
initialEmailValue,
onSuccessCallback: () => {
displayOverlaySpinner();
},
},
signUpFormConfig: {
slots: {
...authPrivacyPolicyConsentSlot,
},
},
resetPasswordFormConfig: {},
})(signInForm);
showModal(signInForm);
},
onSignOutClick: () => {
authApi.revokeCustomerToken();
},
})($login),

Example 2: Render without title and heading content

The following example renders the LoginForm container on a checkout page but without displaying both title and heading content:

import LoginForm from '@dropins/storefront-checkout/containers/LoginForm.js';
import { render as CheckoutProvider } from '@dropins/storefront-checkout/render.js';
const LOGIN_FORM_NAME = 'login-form';
const $login = checkoutFragment.querySelector('.checkout__login');
CheckoutProvider.render(LoginForm, {
displayTitle: false,
displayHeadingContent: false,
})($login),

Example 3: Render with customized title and heading content

The following example renders the LoginForm container on a checkout page providing customized title and heading content:

import LoginForm from '@dropins/storefront-checkout/containers/LoginForm.js';
import { render as CheckoutProvider } from '@dropins/storefront-checkout/render.js';
const LOGIN_FORM_NAME = 'login-form';
const $login = checkoutFragment.querySelector('.checkout__login');
CheckoutProvider.render(LoginForm, {
name: LOGIN_FORM_NAME,
onSignInClick: async (initialEmailValue) => { . . . },
onSignOutClick: () => { . . . },
slots: {
Title: (ctx) => {
const content = document.createElement('div');
content.innerText = 'Custom title';
ctx.replaceWith(content);
},
Heading: (ctx) => {
const content = document.createElement('div');
if (ctx.authenticated) {
// Put here a customized content when the user has signed-in
} else {
// Put here a customized content when the user still has not signed-in
}
ctx.replaceWith(content);
},
},
})($login),

Example 4: Render with callbacks for error handling

The following example renders the LoginForm container on a checkout page providing handlers for validation and API errors:

import LoginForm from '@dropins/storefront-checkout/containers/LoginForm.js';
import { render as CheckoutProvider } from '@dropins/storefront-checkout/render.js';
const LOGIN_FORM_NAME = 'login-form';
const $login = checkoutFragment.querySelector('.checkout__login');
CheckoutProvider.render(LoginForm, {
name: LOGIN_FORM_NAME,
onSignInClick: async (initialEmailValue) => { . . . },
onSignOutClick: () => { . . . },
onCartSyncError: ({ email, error }) => {
const loginFormMsg = document.createElement('div');
loginFormMsg.style.color = 'red';
loginFormMsg.innerText = `Error saving the email address ${email}: ${error.message}`;
$login.appendChild(loginFormMsg);
},
onValidationError: ({ email, message, type }) => {
const loginFormMsg = document.createElement('div');
loginFormMsg.style.color = 'red';
loginFormMsg.innerText = `Validation error (${type}) introducing the email address ${email}: ${message}`;
$login.appendChild(loginFormMsg);
},
})($login),