Home
Wiki
Home
Wiki
  1. 2. Components
  • Back to home
  • 1. Themes
  • Vs Code
    • Getting Started
  • Kitchenware
    • Layout
      • New Layout
      • Legacy Layout
    • Components
      • Announcement
      • Banner Carousel
      • Banner With Products Carousel
      • Blog Category List
      • Blog List
      • Brand List
      • Brands Carousel
      • Breadcrumb
      • Call To Action
      • Cart
      • Categories List
      • Change Password
      • Checkout
      • Cookie Manager
      • Filter list
      • Footer
      • Forgot Password
      • Form
      • Hero Carousel
      • Icon Block
      • Invitation
      • Last Visited Products
      • Layout
      • Login
      • Map
      • Nav Bar
      • Offer
      • Product Attachments
      • Product Attributes
      • Product Documentation
      • Product Expected
      • Product Modal
      • Products Block
      • Products Carousel
      • Product Single
      • Profile
      • Quote
      • Register
      • Related Products
      • Search
      • Stores
      • Subscribe Newsletter
      • Text with Image
      • Top Bar
      • Video
    • Reusables
      • Getting Started
    • Assets
      • Getting Started
    • SDK
      • Products
        • _findProductsByCategory
        • _findProductsByIds
        • _findProductsByTitle
        • _findProductsByFilter
        • _findProductsByCriteria
        • _findProductsAndCalculate
        • _findProductsThenCalculate
        • _getProductAttributeSet
        • _setLastVisited
      • Categories
        • _findCategoryTreeById
        • _findCategoriesByIds
        • _findCategoryByAlias
        • _findCategoryTreeByAlias
        • _getCategoryContent
      • Collections
        • _getCollectionContent
        • _findCollectionsByIds
        • _findCollectionsByIdsThenCalculate
      • Brands
        • _getBrandContent
        • _findBrandsByIds
      • Cart
        • _addToCartMulti
        • _addToCart
        • _setCart
        • _clearCart
        • _setCartListener
        • _removeFromCart
        • _calculateCart
      • Checkout
        • _startCheckout
        • _updateCheckout
        • _completeCheckout
      • Shopping Lists
        • _getShoppingLists
        • _updateShoppingList
        • _createShoppingList
        • _deleteShoppingList
        • _getShoppingListByAlias
      • Navigation
        • _getFooterMenu
        • _getHeaderMenu
      • Users
        • _getUserById
      • Utils
        • _calculateCurrency
        • _getCurrencySymbol
        • _getCulture
        • _subscribeToNewsletter
        • _findUnitsByIds
  • Noir
    • 0. Introduction
    • 1. Structure
      • _Overview
      • LayoutA.liquid
      • ComponentsList.liquid
      • Metas.liquid
      • CssVariables.liquid
      • Json.liquid
      • GoogleTagManager.liquid
      • StagingButton.liquid
    • 2. Components
      • _Overview
      • Announcement
      • BannerCarousel
      • BlogCategoryList
      • BlogList
      • BrandList
      • Breadcrumb
      • Cart
      • CategoriesList
      • ChangePassword
      • Checkout
      • CookieManager
      • FilterList
      • Footer
      • ForgotPassword
      • Form
      • IconBlock
      • Invitation
      • LastVisitedProducts
      • Login
      • Map
      • NavBar
      • ProductAttachments
      • ProductAttributes
      • ProductComparison
      • ProductDocumentation
      • ProductMixList
      • ProductsBlock
      • ProductsCarousel
      • ProductSingle
      • Profile
      • Quote
      • Register
      • RelatedProducts
      • SingleBlog
      • Stores
      • TextWithImage
      • ThankYouPage
      • TopBar
      • Wishlist
    • 3. Reusables
      • _Overview
      • Addresses
      • BillingRetail
      • AddressForm
      • AnnouncementModal
      • BackToTop
      • Company
      • General
      • Login
      • LoginModal
      • MonthlyTransactions
      • Orders
      • Payment
      • ProductAttachments
      • ProductAttributes
      • ProductComparisonButton
      • ProductComparisonFloatingButton
      • ProductGridItem
      • ProductListItem
      • ProductModal
      • ProfileInfo
      • PromptModal
      • Register
      • Services
      • Shipping
      • ShoppingLists
      • ShoppingListsButton
      • ShoppingListsNavbar
      • Toast
      • Transactions
      • Users
      • VariantContent
      • WishlistButton
      • Quotes
    • 4. Assets
      • Fonts
      • Images
      • Templates
      • Javascript
        • _Overview
        • theme.js
      • Css - Scss
        • _Overview
        • ThemeClasses
    • 5. SDK
      • _Overview
      • LiquidGlobals
      • ServicesSDK
  1. 2. Components

NavBar

Purpose#

NavBar renders the storefront header navigation:
Mega menus (Vertical/Horizontal)
Burger menu (desktop overlay + fixed panel)
Simple menu (classic dropdown behavior)
It’s rendered as a header component (SectionHeader).

Inputs (model contract)#

{
  "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",
    "...": "..."
  }
}

Data contract notes (what the template expects)#

model.Settings.Id
model.Settings.showSearch
model.Settings.menuType
model.Settings.menuOrientation
model.Settings.subMenuLevels
Used to render the wrapper id: id="comp-{{ id }}".
Values observed in template logic: Mega, Burger, Simple (and anything else treated as “not simple” in some branches).
Used when menuType == 'Mega' to change layout and which submenu types open on click. Values used: Vertical / Horizontal.
Used to decide whether deeper levels are available/laid out (values used in template: OneLevel, TwoLevels, AllLevels).
Each navigation item can contain nested navigations[] (the template supports deep nesting up to level 4).
Common fields used:
navigationTitle
url
menuIcon.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)
Read at the top of the template; used later in the markup (outside the snippet we reviewed). It’s part of the header UX for announcements/notifications.
Used by the header UI to open/close the announcements drawer.
$store.announcements
$store.loginModal
$store.shoppingLists
$store.cart
model.Settings.CssClass
model.Settings.menuHelperText
model.Settings.showLanguage
model.Settings.showMenuIcons
model.Settings.displayCategoryImages
GlobalData.Settings.logo.link, logoLight.link, favicon.link
GlobalData.Settings.noImage.link (fallback) + theme fallback Assets/images/no-image.svg
GlobalData.Company.Name, GlobalData.Company.Languages
GlobalData.CurrentLanguage / GlobalData.Company.DefaultLanguage
GlobalData.Settings.EnableShoppingLists, EnableWishlist

JavaScript#

Components/NavBar/Default.js defines a global Alpine factory object navbardefault.

navbardefault.initComponent(menuType, menuOrientation)#

Creates the Alpine component state for the navbar/menu system.
State highlights:
isMenuVisible controls whether the element should be present/visible at all.
isMenuOpen controls the slide-in/out class toggles.
On mobile it hides sibling menu items when drilling down into submenu levels.

init()#

resize listener: updates isMobile, then re-measures heights after 500ms
scroll listener: re-measures heights (keeps sticky/fixed layout calculations correct)
Advice:

searchComponent()#

Returns a nested Alpine object used specifically for the search UI.
It exposes:
search()#
hides results and stops loading
shows results + loading
starts a 400ms debounce timer
calls:
servicesreusabledefault.findProductsByCriteria(criteria)
stores the resulting array into resultProducts (if non-empty)
always sets searchLoading = false in finally
Advice:
redirectToSearch()#
/search?s=<encoded query>
Advice:
triggerVoiceSearch()#
Advice:

sendSelectEvent(product, listName, position)#

Advice:

Height/measurement helpers#

Advice:

toggleMenu()#

Handles open/close of the entire menu.
Behaviors:
sets isMenuVisible = true
on mobile:
waits one tick + RAF, then sets isMenuOpen = true
locks body scroll (document.body.style.overflow = "hidden")
measures languageHeight
on desktop, sets isMenuOpen = true immediately
sets isMenuOpen = false
on mobile: waits for transitionend (menu slide-out), then:
resets submenu states
clears hiddenSiblings
unlocks body scroll
sets isMenuVisible = false
on desktop: just hides (isMenuVisible = false)
Advice:

childHover(submenuIndex, hovered)#

(Used by template sections not shown in our snippet; it’s the standard pattern to avoid closing panels while moving the cursor inside complex mega menus.)

getMaxSubmenuHeight(index)#

Purpose:
Measures the maximum height needed to display the submenu panel for submenu${index} (including nested .navbar__menu__sub elements).
Implementation approach:
clones each submenu element off-screen with height: auto / maxHeight: none
reads clone.scrollHeight
returns the max height (+1px “padding” adjustment)
Important note:
In Components/NavBar/Default.js this function wraps its work in setTimeout(..., 300) and the return is inside that callback.
That means the function does not return a height synchronously (callers currently receive undefined).
If you want this.submenuHeight to actually get a numeric value, refactor to either:
compute synchronously (no setTimeout), or
accept a callback / return a Promise and await it.

getMaxBannersHeight(index)#

Purpose:
Measures the height of the banners column inside the submenu (#submenu${index} .banners-wrap > div) using scrollHeight.
Important note:
Same as above: it returns from inside setTimeout(..., 300) so it does not return a value synchronously.

toggleSubmenuLevel1(index)#

toggleSubmenuLevel2(index), toggleSubmenuLevel3(index), toggleSubmenuLevel4(index)#

requires the parent level to be open
maintains:
submenuVisibleLevelN (controls display)
submenuOpenLevelN (controls the slide transition state)
on mobile, it waits for transitionend when closing so it can clear submenuVisibleLevelN.
Advice:
visible keeps the element in the DOM for animation.
open controls translate classes.

handleResize()#

Resets menu state on resize, and:
if mobile: false
if desktop and menuType == Burger: false
else: true

resetMenu()#

Resets the menu when clicking outside (@click.away="resetMenu" in Liquid).
Very similar to handleResize() but doesn’t recompute isMobile.

navbardefault.handleLogout(logout, modalMessageText, modalButtonCancel)#

Opens a confirmation modal using Alpine.store("modal").open(...).
If user confirms:
cartToken, cartData, checkoutToken
Advice:

Global Alpine stores (used by NavBar)#

From JS + template conventions, NavBar relies on these global items being present in the theme runtime:
Used by navbardefault.handleLogout(...) to show a confirmation modal.
Used by search live results (findProductsByCriteria).
Must exist globally before NavBar JS runs.
sendGAEvent(...)
prepareListProducts(...)
Additionally, based on common Noir patterns, the header may interact with other global stores in adjacent header components.

Web Speech API (optional voice search)
GlobalData: logo, company, languages, feature flags (wishlist/shopping lists)

Notes#

There’s a likely typo in the banners CTA section:
If a promo banner CTA isn’t working, verify the correct property name and fix the Liquid accordingly.
If the storefront language isn’t English, this can feel inconsistent; consider routing the error and messaging through the toast store and mapping language.
Menu breakpoint is hardcoded at 1440px.
If design breakpoints change, update both Liquid responsiveness assumptions and this JS constant.

Extras#

If GlobalData.Settings.logo.link or logoLight.link exists, the navbar renders <img> logo(s).
If no logo exists, it falls back to showing the company name.
The root Alpine scope is created via:
NOIR_CODEBLOCK_0
There’s one “menu button” that toggles visibility, and a wrapper that:
behaves differently on mobile vs desktop (isMobile = window.innerWidth < 1440)
changes layout based on menuOrientation and subMenuLevels
Submenus:
The template supports (and the JS tracks) open/visible state for:
level 1: submenuOpenLevel1, submenuVisibleLevel2
level 2: submenuOpenLevel2, submenuVisibleLevel3
level 3: submenuOpenLevel3, submenuVisibleLevel4
level 4: submenuOpenLevel4
On mobile, submenus slide horizontally and show a “Back” button per level.
On desktop, submenus are shown/hidden by setting inline display: styles based on open/visible properties.
A search button toggles a search panel.
The search panel contains an <input type="search"> bound to searchText.
Typing triggers a debounced API search and shows up to 5 items (+1 extra is fetched so the UI can decide “show all” behavior).

Language switcher (mobile)#

If there are multiple languages (GlobalData.Company.Languages.size > 1):
A mobile-only language listbox is rendered inside the menu wrapper.
It uses a small local Alpine scope: x-data="{ open: false }".
Modified at 2026-05-04 12:08:29
Previous
Map
Next
ProductAttachments
Built with