Purpose#
Login is the reusable that renders and handles the storefront login form flow.It validates credentials, triggers authentication calls, and handles login feedback/navigation.Where it's rendered#
It’s rendered in multiple places:Components/Login/Default.liquid
Reusables/LoginModal/Default.liquid
From Components/Login/Default.liquid:{% render 'Reusables\\Login\\Default', uniquekey: uniquekey %}
Login is rendered with a single parameter.Model shape (storefront example)#
Not applicable (this reusable doesn’t receive a platform model object).It receives only uniquekey from the caller (generated in Liquid) to create unique input ids/names.Required fields#
Used to generate deterministic DOM ids/names:login-email-{{ uniquekey }}
login-password-{{ uniquekey }}
field names are also suffixed with the same value.
Optional fields#
Template behavior (Liquid + Alpine)#
Source: Reusables/Login/Default.liquid.Root form uses Alpine data:
x-data="loginreusabledefault.initComponent()"
Submission is handled by @submit.prevent, passing translations (toast messages):
@submit.prevent="checkForm('{{ uniquekey }}', ...toast messages...)"
Password visibility is toggled via toggleVisibility($event).
Data contract (JS runtime)#
The Alpine object is loginreusabledefault from Reusables/Login/Default.js.fields (array of input elements)
errors (object map: fieldName -> errorType)
JavaScript#
Global object#
File: Reusables/Login/Default.jsExposes: loginreusabledefaultinitComponent#
Returned members#
Returns a fresh Alpine state object per Login instance, including:methods: init, validateField, toggleVisibility, updateFormValidity, clearForm, checkForm
init#
Runs when the Alpine instance is mounted for a specific Login form.
Collects all form fields from the current form element (this.$el) except:elements marked with .skipped
Attaches blur validation listeners so each field is validated when the user leaves it.
Subscribes to clear-login-modal-forms window event to reset form state when modal flows require it.
Optionally clears toast messages unless preserveToasts is set in the event payload.
validateField#
Validates one field and stores an error code in errors[field.name].
Current validation rules:required fields -> required when empty
email fields -> invalidEmail when regex check fails
Toggles CSS classes on inputs:invalid for invalid required fields
valid for valid required fields
Updates the related .icon-state element to reflect warning/success state.
toggleVisibility#
Handles password visibility toggle from the checkbox controls.
Maps toggle input id (e.g. toggle-login-password-...) to the real password input id.
Updates icon class (ic-eye-off / ic-preview) and checkbox state.
Returns true only if all tracked fields are valid.
Treats form as invalid when:any field has an error in errors
any required field is still empty
Used as the final gate before submitting login to the API.
Clears all tracked field values.
Removes valid / invalid classes from inputs.
Resets field icon-state classes.
Resets errors object to empty.
Used after successful login and on modal reset events.
Main submit handler for login.
Clears toast stack ($store.toast.removeAll()).
Stops immediately if form is invalid.
Sets isSending = true to prevent duplicate submissions.
Calls servicesreusabledefault.accountLogin(payload).
409 -> shows locked-account toast
other failures -> resets visual field state and shows credentials error toast
Resets isSending and exits.
Clears form and shows success toast.
1.
external redirect from ?redirect=http(s)://...
2.
if current page is /login -> redirect to / after short delay
3.
if login modal requested checkout continuation -> go to /checkout
4.
fallback -> window.location.reload()
Finally resets isSending.
Global Alpine stores#
removeAll() and add(...) for feedback.
Reads and updates goToCheckoutPage to decide whether to redirect to checkout.
Services / API calls#
servicesreusabledefault.accountLogin({ Email, Password })
Dependencies#
Reusables/Login/Default.liquid
Reusables/Login/Default.js
Reusables/Login/Default.json (translations)
Components/Login/Default.liquid (render on login page)
Reusables/LoginModal/Default.liquid (render in modal)
$store.toast and $store.loginModal in Assets/js/theme.js
servicesreusabledefault.accountLogin
Notes#
The reusable expects the generated uniquekey to be unique per instance, otherwise the document.querySelector('#login-email-' + uniquekey) selectors may target the wrong input.
For security, the redirect logic only allows absolute redirects when they come from the ?redirect=http(s)://... query string.
Examples#
{% render 'Reusables\\Login\\Default', uniquekey: uniquekey %}
{% render 'Reusables\\Login\\Default', uniquekey: uniquekey %}
Modified at 2026-06-16 08:26:59