NavBar renders the storefront header navigation:Mega menus (Vertical/Horizontal)Burger menu (desktop overlay + fixed panel)Simple menu (classic dropdown behavior)SectionHeader).{
"unReadAnnouncements": 0,
"navigations": [
{
"navigationTitle": "Sample navigation title",
"url": "/sample",
"image": {},
"banners": [],
"bannersLink": "",
"bannersText": "Sample text",
"menuIcon": {},
"navigations": [
{
"navigationTitle": "Sample navigation title",
"url": "/sample",
"image": {
"id": "Image Id",
"link": "https://example.com/media/sample.jpg"
},
"banners": [
{
"image": {
"id": "Banner image Id",
"link": "https://example.com/media/sample-banner.jpg"
}
},
"..."
],
"bannersLink": "",
"bannersText": "Sample text",
"menuIcon": {},
"navigations": [
{
"navigationTitle": "Sample navigation title",
"url": "/sample",
"image": {
"id": "Image Id",
"link": "https://example.com/media/sample.jpg"
},
"banners": [],
"bannersLink": "",
"bannersText": "",
"menuIcon": {},
"navigations": [
{
"navigationTitle": "Sample navigation title",
"url": "/sample",
"image": {
"id": "Image Id"
},
"banners": [],
"bannersLink": "",
"bannersText": "",
"menuIcon": {}
},
"..."
]
},
"..."
]
},
"..."
]
},
"..."
],
"name": "NavBar",
"view": "Default",
"section": "SectionHeader",
"settings": {
"showSearch": true,
"showLanguage": false,
"showMenuIcons": false,
"displayCategoryImages": false,
"menuType": "Mega",
"menuOrientation": "Vertical",
"subMenuLevels": "AllLevels",
"menuHelperText": "Sample text",
"id": "Component Id",
"section": "SectionHeader",
"type": "NoirNavBar",
"name": "NavBar",
"configuredInContentApi": true,
"view": "Default",
"displayName": "",
"cssClass": "",
"header": "",
"alignment": "Left"
},
"translations": {
"navbarLogoFor": "Sample text",
"goToHomepage": "Sample text",
"openLoginModal": "Sample text",
"...": "..."
}
}model.Settings.Idid="comp-{{ id }}".model.Settings.menuTypeMega, Burger, Simple (and anything else treated as “not simple” in some branches).model.Settings.menuOrientationmenuType == 'Mega' to change layout and which submenu types open on click. Values used: Vertical / Horizontal.model.Settings.subMenuLevelsOneLevel, TwoLevels, AllLevels).model.navigations[]navigations[] (the template supports deep nesting up to level 4).navigationTitleurlmenuIcon.link (used only for Burger menu + when showMenuIcons = true)image.link (used for category image previews in Mega Horizontal when displayCategoryImages = true)banners[] (used for Mega Vertical to show promotional banners to the side)bannersText, bannersLink (note: the template checks these, but the link is referenced as nav.bannerLink in one place—see Notes)model.unReadAnnouncementsGlobalData):GlobalData.Settings.logo.link, logoLight.link, favicon.linkGlobalData.Settings.noImage.link (fallback) + theme fallback Assets/images/no-image.svgGlobalData.Company.Name, GlobalData.Company.LanguagesGlobalData.CurrentLanguage / GlobalData.Company.DefaultLanguageGlobalData.Settings.EnableShoppingLists, EnableWishlistDefault.js defines a global Alpine factory object navbardefault.navbardefault.initComponent(menuType, menuOrientation)isMobile: computed from window.innerWidth < 1440 (updated on resize).isMenuVisible / isMenuOpen: two-phase open animation control.isMenuVisible controls whether the element should be present/visible at all.isMenuOpen controls the slide-in/out class toggles.hiddenSiblings:init()topbarHeight and navbarHeight.resize listener: updates isMobile, then re-measures heights after 500msscroll listener: re-measures heights (keeps sticky/fixed layout calculations correct)updateTopbarHeight() / updateNavbarHeight() still match.searchComponent()searchText, resultProducts, flags like showSearchResult, searchLoadingmaxSearchResult = 5search() method and navigation helpers.search()searchText is empty:servicesreusabledefault.findProductsByCriteria(criteria)resultProducts (if non-empty)searchLoading = false in finallyservicesreusabledefault being loaded globally (it’s a reusable service layer).maxSearchResult, keep pageSize = maxSearchResult + 1 pattern so the UI can infer “there are more results”.redirectToSearch()searchText.trim() isn’t empty, redirects to:/search?s=<encoded query>/search with query param s. If the Search page changes its query contract, update this.triggerVoiceSearch()SpeechRecognition or webkitSpeechRecognition).alert()s an English message.searchText and shows the results panel.en-US. If you want it localized, map it from GlobalData.CurrentLanguage.alert() with the theme toast store for consistent UX.sendSelectEvent(product, listName, position)prepareListProducts([product]).sendGAEvent("selectItem", { listName, items, position }).prepareListProducts, sendGAEvent).prepareListProducts expects (typically includes id, name, price, brand, etc.).updateNavbarHeight(): reads .navbar heightupdateLanguageHeight(): reads .navbar__menu__wrapper .language-wrapper heightupdateTopbarHeight(): reads .topbar heightmenuHeight getter: window.innerHeight - topbarHeightmenuPaddingTop getter: returns navbarHeight as a fallback padding-toptoggleMenu()isMenuVisible = trueisMenuOpen = truedocument.body.style.overflow = "hidden")languageHeightisMenuOpen = true immediatelyisMenuOpen = falsetransitionend (menu slide-out), then:hiddenSiblingsisMenuVisible = falseisMenuVisible = false)this.$refs.mobileMenu still has a CSS transition; otherwise transitionend might never fire and the state won’t reset.childHover(submenuIndex, hovered)submenuHovered[submenuIndex].getMaxSubmenuHeight(index)#submenu{index} then uses its parentNode as the root group..navbar__menu__sub elements.scrollHeight.getMaxBannersHeight(index)#submenu{index} .banners-wrap > div scrollHeight.toggleSubmenuLevel1(index)hiddenSiblings[1] to hide other level-1 list items.submenuHeight and bannersHeight, and recomputes after $nextTick().toggleSubmenuLevel2(index), toggleSubmenuLevel3(index), toggleSubmenuLevel4(index)submenuVisibleLevelN (controls display)submenuOpenLevelN (controls the slide transition state)submenuVisibleLevelN.visible keeps the element in the DOM for animation.open controls translate classes.handleResize()isMenuVisible based on breakpoint and menu type:resetMenu()@click.away="resetMenu" in Liquid).handleResize() but doesn’t recompute isMobile.navbardefault.handleLogout(logout, modalMessageText, modalButtonCancel)Alpine.store("modal").open(...).cartToken, cartData, checkoutToken/account/logoutmodal store exists.Alpine.store("modal")navbardefault.handleLogout(...) to show a confirmation modal.servicesreusabledefaultfindProductsByCriteria).sendGAEvent(...)prepareListProducts(...)$store.cart (cart popup / cart counter)$store.toast (errors like AddToCartErrorMessage / UpdateProductQuantityErrorMessage)$store.loginModal / $store.account (login/register modal)$store.announcement (announcements modal + unread count)$store.wishlist, $store.shoppingLists (feature-flagged icons in header)Default.js, but they’re often used in the rest of Default.liquid (icons / popups / modals) and/or in other header components that appear alongside NavBar.servicesreusabledefault.findProductsByCriteriasendGAEvent, prepareListProductsnav.bannersLink but later uses nav.bannerLink for the <a href="...">.triggerVoiceSearch() uses alert() and hardcodes recognition.lang = "en-US".1440px.GlobalData.Settings.logo.link or logoLight.link exists, the navbar renders <img> logo(s).favicon.link as a small logo; if missing it falls back to company initials.isMobile = window.innerWidth < 1440)menuType (Burger vs Mega vs Simple)menuOrientation and subMenuLevelssubmenuOpenLevel1, submenuVisibleLevel2submenuOpenLevel2, submenuVisibleLevel3submenuOpenLevel3, submenuVisibleLevel4submenuOpenLevel4display: styles based on open/visible properties.model.Settings.showSearch is true:<input type="search"> bound to searchText.GlobalData.Company.Languages.size > 1):x-data="{ open: false }".