GlobalData.Company and GlobalData.Settingsmodel.Navigations$store.darkMode){
"navigations": [
{
"navigationTitle": "Sample navigation title",
"navigationType": "Link",
"url": "/sample",
"navigations": [
{
"navigationTitle": "Sample navigation item",
"navigationType": "Category",
"relativeId": "Navigation Relative Id",
"url": "/category/sample",
"image": {
"id": "Image Id",
"link": "https://example.com/media/sample.jpg",
"mediaType": "Image"
},
"navigations": [],
"isMegaMenu": false,
"megaMenuWithImages": false,
"megaMenuPosition": "Horizontal",
"banners": []
},
"..."
],
"isMegaMenu": false,
"megaMenuWithImages": false,
"megaMenuPosition": "Horizontal",
"banners": []
},
"..."
],
"name": "Footer",
"view": "Default",
"section": "SectionFooter",
"settings": {
"showNewsletterSubcription": true,
"socialBlock": {
"socials": [
{
"link": "https://example.com/social",
"socialName": "Sample"
},
"..."
]
},
"paymentMethods": [
{
"name": "Sample payment method",
"image": {
"link": "https://example.com/media/sample-payment.svg"
}
},
"..."
],
"id": "Component Id",
"section": "SectionFooter",
"type": "NoirFooter",
"name": "Footer",
"configuredInContentApi": true,
"view": "Default",
"displayName": "",
"cssClass": "",
"header": "",
"alignment": "Left"
},
"translations": {
"allRightsReserved": "Sample text",
"poweredBy": "Sample text",
"subscribeNewsletter": "Sample text",
"...": "..."
}
}settings.idcomp-{{ id }}.navigations[]settings.cssClass(UNDEFINED).settings.showNewsletterSubcription (boolean)true, the newsletter subscription block is rendered.settings.socialBlock.socials[]settings.paymentMethods[]translations.*showNewsletterSubcription).errors: {}"footer-subscribe".isSending: falsesuccessSubmission, errorSubmission"show" / "hide") and drive updateSubmissionStatus().navigations: []errors as the single source of truth for inline validation.validateField(field)"required")"invalidEmail")this.errors = {} before validating (so only one error is shown at a time).this.errors["footer-subscribe"] = errorType.invalid when invalid.valid when validtrue if valid, otherwise false.field.closest("div"). If markup changes, validation styling may break.updateSubmissionStatus()"footer .submission-status .success""footer .submission-status .error"show class from both.show based on:this.successSubmission === "show"this.errorSubmission === "show"x-show for submission status. That’s okay, but it means:x-show + state only (no DOM querying).submitSubscribeForm() (async)#footer-subscribevalidateField(emailInput).isSending = trueservicesreusabledefault.subscribeNewsletter(email))successSubmission = "show" and clear inputerrorSubmission = "show"isSending = falseupdateSubmissionStatus()$store.toast) for consistent theme messaging.$store.darkMode (theme color mode)@click="$store.darkMode.toggle()":aria-checked="$store.darkMode.on":class="{ 'active': $store.darkMode.on }":aria-label="$store.darkMode.on ? 'Disable...' : 'Enable...'"x-text inside an .sr-only element$store.darkMode is not initialized in Assets/js/theme.js, the toggle will not work and Alpine will throw errors when clicking.x-data and for dark mode toggle bindings)$store.darkModeGlobalData (company/settings info)ic-facebook, ic-instagram, etc.)target="_blank"). Consider adding rel="noopener noreferrer" if you want the strictest security posture for external links.settings.showNewsletterSubcription is truthy.x-data="footerdefault"@submit.prevent="submitSubscribeForm()"x-show="errors['footer-subscribe'] === 'required'"x-show="errors['footer-subscribe'] === 'invalidEmail'"successSubmissionerrorSubmissionloading="lazy".model.navigations[]:nav.navigations.size > 0ic-{{ social.SocialName | downcase }}target="_blank" (external).settings.paymentMethods[].alt falls back to:<paymentMethod.Name> + translations.logo@click="$store.darkMode.toggle()":aria-checked="$store.darkMode.on":class="{ 'active': $store.darkMode.on }"