Purpose#
Register is the reusable that renders and handles storefront user-registration flows.It validates registration inputs and coordinates registration submission/feedback behavior.Where it's rendered#
It’s rendered in multiple places:Components/Register/Default.liquid
Reusables/LoginModal/Default.liquid
From Components/Register/Default.liquid:{% render 'Reusables\\Register\\Default', uniquekey: uniquekey %}
Liquid parameters#
Used to make DOM ids/names unique.
The template appends it to all field id/name attributes.
Model shape (storefront example)#
Sanitized real storefront example (provided by the user) of the component/page model that renders registration:{
"name": "Register",
"view": "Default",
"section": "SectionA",
"settings": {
"retypePassword": false,
"id": "Component Id",
"section": "SectionA",
"type": "Register",
"name": "Register",
"configuredInContentApi": false,
"view": "Default",
"displayName": "",
"cssClass": "",
"header": "",
"alignment": "Left"
},
"translations": {
"registerAccount": "Sample text",
"alreadyAccount": "Sample text",
"login": "Sample text"
}
}
The reusable itself relies mostly on Reusables.Register.Translations.* and does not read the page translations object directly.
Registration is feature-gated by GlobalData.Settings.showRegistration inside the reusable template.
Template behavior (Liquid + Alpine)#
Feature flag#
The form is rendered only when:GlobalData.Settings.showRegistration is truthy.
Alpine wiring#
Alpine component (factory):
x-data="registerreusabledefault.initComponent(captchaEnabled, captchaSiteKey, captchaActionId, captchaChallenge)"@submit.prevent="checkForm(uniquekey, successMessage, errorMessageFail, errorMessageUserExists)"
Fields#
All fields are required unless stated otherwise:First name (register-firstname-<uniquekey>) (required)
Last name (register-lastname-<uniquekey>) (required)
Email (register-email-<uniquekey>) (required, email format)
Password (register-password-<uniquekey>) (required, must pass weak-password rules)
Confirm password (register-confirm-password-<uniquekey>) (required, must match password)
Terms consent checkbox (register-terms-<uniquekey>) (required)
Password visibility#
Both password fields include a toggle checkbox that triggers toggleVisibility($event) to switch the input type between password and text.Data contract (JS runtime)#
Document runtime state shape, factories, and main state fields.JavaScript#
Global object#
File: Reusables/Register/Default.jsExposes: registerreusabledefaultinitComponent#
Returned members#
Returns a fresh Alpine state object per Register instance.
fields, errors, isSending
password-rule flags (errorUpLowCase, errorLength, errorSymbolNum)
captcha state (captchaEnabled, captchaSiteKey, captchaActionId, captchaChallenge, captchaToken, captchaError, observers)
Exposes methods used by the form lifecycle and captcha flow.
init#
Runs when the Alpine instance mounts for a specific Register form.
Collects valid field elements from the current form (this.$el) and attaches:blur validation listeners for standard inputs
change listeners for required checkboxes
If enterprise captcha challenge mode is enabled, starts challenge initialization.
Subscribes to clear-login-modal-forms to reset form + captcha state when modal flows request clearing.
validateField#
Validates a single field and writes an error code to errors[field.name].
Handles required checks, email format, password strength rules, and confirm-password matching.
Updates input classes and icon state to reflect valid/invalid UI.
toggleVisibility#
Toggles a password input between type="password" and type="text".Used by the password “eye” toggle checkbox in the template.Returns true only when tracked fields have no active errors and required values are present.
Used as the final gate before registration submission.
Resets all form inputs and clears validation UI state.Also called when clearing modal forms via the clear-login-modal-forms event.Main submit handler for registration.
Clears toasts ($store.toast.removeAll()).
Validates all fields and aborts on invalid input.
Sets isSending = true to avoid duplicate submissions.
Builds registration payload from form fields.
If captcha is enabled, retrieves token via getEnterpriseCaptchaToken() and forwards it in request headers.
Calls servicesreusabledefault.accountRegister(...).
Handles duplicate-user / general failure responses with dedicated toasts.
Keeps form visible for correction and resets isSending.
Clears form, resets captcha state as needed, shows success toast.
Redirects/reloads according to page/modal flow.
findResponseEl#
Helper used during captcha challenge mode.Finds the textarea[name='g-recaptcha-response'] element (scoped to the form when possible) so the JS can read token updates.getEnterpriseCaptchaToken#
Returns the captcha token that should accompany the registration request.Non-challenge mode: calls grecaptcha.enterprise.execute(siteKey, { action }).
Challenge mode: reads the widget response from the hidden g-recaptcha-response textarea (or widget API when available).
initCaptchaChallenge#
Initializes captcha challenge mode behavior.Wires observers/listeners so the component can detect when the user completes (or expires) the checkbox challenge and keep captchaToken in sync.onTokenMaybeChanged#
Internal helper used by initCaptchaChallenge().Runs whenever the captcha response textarea potentially changes (mutation observer / events / click rechecks) and updates captchaToken + captchaError state.recheck#
Internal helper used by the captcha challenge flow to re-read the token shortly after interactions (covers async widget updates).resetCaptcha#
Clears local captcha state and disconnects observers.Called after clearing forms (e.g. when closing the login modal) and when a fresh captcha verification is needed.set#
Internal helper used by initCaptchaChallenge().Hooks into the captcha response textarea’s .value setter so the component can react even when the widget updates the value without triggering standard DOM events.tick#
Internal helper used by initCaptchaChallenge().Runs a short, self-canceling polling loop to detect slow async fills of the captcha response.waitForGrecaptcha#
Internal helper used by initCaptchaChallenge().Waits (briefly) for window.grecaptcha to become available because the captcha script is loaded async/defer.Global Alpine stores#
add(message, icon, type, autoClose)
Services / API calls#
servicesreusabledefault.accountRegister(info)Request payload shape (as built by the JS):{
"FirstName": "Sample text",
"LastName": "Sample text",
"Email": "sample@example.com",
"Password": "Sample text",
"ValidatePassword": "Sample text"
}
Dependencies#
Liquid: Reusables/Register/Default.liquid
JS: Reusables/Register/Default.js
Translations: Reusables/Register/Default.json
Components/Register/Default.liquid
Reusables/LoginModal/Default.liquid
servicesreusabledefault.accountRegister(...)
Notes#
The template uses uniquekey to avoid DOM id collisions when the same form appears more than once (e.g. inside the login modal).
The password rules are enforced client-side; backend should enforce the same (or stricter) policy.
The form is gated by GlobalData.Settings.showRegistration; when disabled, this reusable renders nothing.
Modified at 2026-06-16 08:27:50