Purpose#
LoginModal is the global modal used to authenticate users without leaving the current page.It renders a tabbed UI (Login / Register when enabled), can optionally show a “shopping list” message, and can optionally show a “checkout as guest” link depending on store settings.The modal’s visibility and context are controlled by the global Alpine store $store.loginModal.Where it's rendered#
It’s rendered globally from the theme layout so it’s available site-wide.From Structure/LayoutA.liquid:{% render 'Reusables\\LoginModal\\Default' %}
LoginModal is rendered without parameters.Model shape (storefront example)#
Not applicable (this reusable doesn’t receive a platform model object and has no Liquid render parameters).Required fields#
Optional fields#
Template behavior (Liquid + Alpine)#
Source: Reusables/LoginModal/Default.liquid.Unique key generation#
The template generates a unique key (uniquekey) per render so the nested Login/Register forms can use unique DOM ids:{% assign uniquekey = 'login-modal' | append: '-' | append: part1 | append: '-' | append: part2 %}
Alpine state (local)#
The wrapper uses a local Alpine state for the active tab:<div x-data="{ tab: 'login' }" x-cloak>
Visibility + lifecycle#
The overlay and modal are shown when:
$store.loginModal.visible
When the modal finishes closing it flushes state:
@after-leave="$store.loginModal.flush()"
Clicking outside closes the modal:
@click.outside="$store.loginModal.close()"
Modal title#
The title switches based on the local tab state.
The close button uses the PromptModal translation for aria-label:
aria-label="{{ Root.Reusables.PromptModal.Translations.CloseModalMessage }}"
Tabs + content#
When GlobalData.Settings.showRegistration is enabled:{% render 'Reusables\\Login\\Default', uniquekey: uniquekey %}
{% render 'Reusables\\Register\\Default', uniquekey: uniquekey %}
When $store.loginModal.showShoppingListMessage is true, a message is shown at the top:Reusables.LoginModal.Translations.ShoppingListMessage
Checkout as guest#
When GlobalData.Settings.allowAnonymousCheckout is true, and $store.loginModal.checkoutPage is true, a guest-checkout hint is shown:Reusables.LoginModal.Translations.CheckoutAsGuest
Reusables.LoginModal.Translations.CheckoutAsGuestBtn
Data contract (JS runtime)#
Reusables/LoginModal/Default.js defines an empty object:Runtime behavior is driven by $store.loginModal (defined in Assets/js/theme.js) and by the nested Login / Register reusables.JavaScript#
There is no reusable-specific JavaScript logic in LoginModal.If you need to debug behavior, look at:$store.loginModal in Assets/js/theme.js
Reusables/Login/Default.js
Reusables/Register/Default.js
Global Alpine stores#
open(fromCheckout, fromShoppingList)
Other stores used indirectly:Used by Login/Register to show feedback.
Services / API calls#
Services are called by nested reusables:servicesreusabledefault.accountLogin(...) (Login)
(Register has its own API calls)
Dependencies#
Structure/LayoutA.liquid (global render site)
Reusables/LoginModal/Default.liquid
Reusables/LoginModal/Default.js
Reusables/LoginModal/Default.json (translations)
Reusables/Login/Default.liquid + Default.js
Reusables/Register/Default.liquid + Default.js
$store.loginModal in Assets/js/theme.js
Notes#
The modal’s content depends on store settings:GlobalData.Settings.showRegistration (tabs and register form)
GlobalData.Settings.allowAnonymousCheckout (guest checkout hint)
The close aria-label is sourced from PromptModal translations (not LoginModal translations).
Examples#
{% render 'Reusables\\LoginModal\\Default' %}
Modified at 2026-04-14 13:18:56