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
    • 6. FAQ
    • 1. Structure
      • _Overview
      • LayoutA.liquid
      • ComponentsList.liquid
      • Metas.liquid
      • CssVariables.liquid
      • Json.liquid
      • GoogleTagManager.liquid
      • StagingButton.liquid
    • 2. Components
      • _Overview
      • Announcement
      • BannerCarousel
      • BlogCategoryList
      • BlogHighlights
      • BlogList
      • BrandList
      • Breadcrumb
      • Cart
      • CategoriesList
      • ChangePassword
      • Checkout
      • CookieManager
      • CustomTable
      • Faq
      • FilterList
      • Footer
      • ForgotPassword
      • Form
      • IconBlock
      • Invitation
      • LastVisitedProducts
      • Login
      • Map
      • NavBar
      • Offer
      • ProductAttachments
      • ProductAttributes
      • ProductComparison
      • ProductDocumentation
      • ProductMixList
      • ProductsBlock
      • ProductsCarousel
      • ProductSingle
      • Profile
      • Quote
      • Register
      • RelatedProducts
      • SingleBlog
      • Stores
      • TextWithImage
      • ThankYouPage
      • TopBar
      • Wishlist
    • 3. Reusables
      • _Overview
      • Addresses
      • AddressForm
      • AnnouncementModal
      • BackToTop
      • BillingRetail
      • BlogPostingStructuredData
      • BrandListStructuredData
      • CollectionStructuredData
      • Company
      • General
      • GroupChildrenTable
      • Login
      • LoginModal
      • MonthlyTransactions
      • Offers
      • Orders
      • Payment
      • ProductAttachments
      • ProductAttributes
      • ProductAvailabilityAction
      • ProductComparisonButton
      • ProductComparisonFloatingButton
      • ProductGridItem
      • ProductGridItemClassic
      • ProductListItem
      • ProductModal
      • ProductStructuredData
      • ProfileInfo
      • PromptModal
      • Quotes
      • Register
      • Services
      • Shipping
      • ShoppingLists
      • ShoppingListsButton
      • ShoppingListsNavbar
      • StoresStructuredData
      • Toast
      • Transactions
      • Users
      • VariantContent
      • VariantContentClassic
      • WishlistButton
    • 4. Assets
      • Fonts
      • Images
      • Templates
      • Javascript
        • _Overview
        • theme.js
      • Css - Scss
        • _Overview
        • ThemeClasses
    • 5. SDK
      • _Overview
      • LiquidGlobals
      • ServicesSDK
  1. 2. Components

Map

Purpose#

The Map component renders an interactive map using Leaflet and places a marker for a configured location.
It supports:
A single marker based on settings.latitude / settings.longitude
Optional custom marker icon (settings.marker.link)
A popup with:
address (composed from settings address fields)
optional phone/email links
“View directions” link (Google Maps search by coordinates)
Map zoom control via settings.zoom

Inputs (model contract)#

Model shape (storefront example)#

{
  "name": "Map",
  "view": "Default",
  "section": "SectionA",
  "settings": {
    "address": {
      "address1": "Sample address",
      "city": "Sample city",
      "state": "Sample state",
      "country": "Sample country",
      "postalCode": "Sample postal code",
      "translation": {}
    },
    "latitude": "37.947045",
    "longitude": "23.703733",
    "zoom": 14,
    "imageTranslation": {},
    "id": "Component Id",
    "section": "SectionA",
    "type": "Map",
    "name": "Map",
    "configuredInContentApi": false,
    "view": "Default",
    "displayName": "",
    "cssClass": "",
    "header": "",
    "alignment": "Left"
  },
  "translations": {
    "map": "Sample text",
    "viewDirections": "Sample text",
    "...": "..."
  }
}

Required fields#

settings.id
Used for wrapper id: comp-{{ id }} and map container id: map-{{ id }}.
settings.latitude, settings.longitude
Coordinates used to create the Leaflet marker.
In the theme they are passed as strings and converted to numbers in JS.

Optional fields#

settings.cssClass
Applied only when non-empty and not (UNDEFINED).
settings.header
Rendered as a title above the map when provided.
settings.zoom
Used as initial zoom (fallback is 14 when not valid).
Address fields are concatenated into a single string used in the marker popup.
model.Settings.Address (object)
Used by Liquid to build the address string passed into JavaScript.
settings.phone, settings.email
Optional popup lines:
tel: link
mailto: link
These exist in the Liquid template (model.Settings.Phone, model.Settings.Email) even if not present in your example model.
model.Settings.Marker
Optional custom marker icon URL.
Field used by the template: model.Settings.Marker.link
The template also reads:
model.Settings.Alignment (used to derive wrapper alignment classes)
translations.viewDirections
Used as the “View directions” link text inside the marker popup.

Template behavior (Liquid + Alpine)#

Describe rendering flow, state branches, and key Liquid/Alpine behavior.

JavaScript#

Global object#

The component exposes:

initComponent#

Factory that converts inputs into normalized state:
zoom: Number(zoom)
lat: Number(lat)
long: Number(long)
string fallbacks for address/phone/email/markerLink
Tracks created markers in:
markers: []
Exposes methods:
init()
addMarkers() (async)
Notes:
Latitude/longitude must be numeric strings. If they’re empty or invalid, no marker will be placed.

init#

1.
Creates the Leaflet map instance:
this.map = L.map("map-" + this.id)
2.
Adds the tile layer (keyless OpenStreetMap tiles):
https://tile.openstreetmap.org/{z}/{x}/{y}.png
with attribution and maxZoom: 19
calls watchTileAvailability(tiles) before adding the layer to the map
3.
Determines a safe default zoom:
uses this.zoom if finite, else 14
4.
Sets an initial view (temporary):
this.map.setView([20, 0], defaultZoom)
(This is just a neutral starting point before markers are added.)
5.
Calls addMarkers() and then adjusts the view:
If exactly one marker:
centers on marker at defaultZoom
If multiple markers:
fits bounds with padding
Notes:
Leaflet must be loaded globally (L must exist), otherwise initialization will throw.
The component is implemented as if it could support multiple markers (bounds logic), even though the current Liquid only provides one coordinate set.

watchTileAvailability#

Stores the tile layer on this.tileLayer and listens for tile errors, so a refused basemap is flagged instead of looking like a broken map.
After 5 consecutive tileerror events it sets tilesUnavailable = true and adds the map-tiles-unavailable class to the map container.
Any tileload resets the failure counter and removes the class.
Markers, popups and the directions link keep working while tiles are unavailable.

retryTiles#

Resets the failure state and redraws the tile layer.
Clears tileFailures and tilesUnavailable and removes map-tiles-unavailable, so the first failed tile of the retry does not immediately re-flag the outage.
Does nothing when no tile layer has been registered.

addMarkers#

1.
Creates a MarkerCluster group:
const markerCluster = L.markerClusterGroup();
2.
Validates coordinates:
if lat/long are not finite → returns early (no marker)
3.
Creates marker:
If markerLink exists:
uses a custom icon via L.icon({ iconUrl, iconSize, iconAnchor, popupAnchor })
Else:
uses default Leaflet marker
4.
Binds a popup HTML template that can include:
Address line (only if address exists)
Phone line (only if phone exists)
Email line (only if email exists)
“View directions” link if coordinates are valid:
https://www.google.com/maps/search/?api=1&query=<lat>,<long>
label uses viewDirectionsTranslation
5.
Adds marker to the cluster, stores it in this.markers, adds cluster to map.
6.
Fits bounds to all markers with padding.
Notes:
MarkerCluster must be loaded (L.markerClusterGroup). If marker cluster plugin isn’t loaded, this will throw. (No fallback is implemented.)
Popup HTML is built with template literals. If you ever include user-generated strings, ensure backend sanitization to avoid injection.
The “View directions” link always uses Google Maps, even though the map tiles are OpenStreetMap/CARTO. That’s a product decision; if you want OSM directions you’d change the URL.

Dependencies#

Leaflet (global L)
Leaflet MarkerCluster plugin (global L.markerClusterGroup)
Internet access to load CARTO tiles
Optional: a custom marker image URL (settings.marker.link)

Notes#

Even though the component supports multi-marker bounds logic, the current settings structure provides only one coordinate pair.
If coordinates are invalid/missing, map renders but no marker will be added.

Extras#

Template behavior (Liquid + Alpine)#

Initialization#

The component mounts Alpine using the JS factory:
x-data='mapdefault.initComponent(id, lat, long, address, phone, email, markerLink, zoom, viewDirectionsTranslation)'
Important:
Liquid builds a single address string from model.Settings.Address fields (Address1/City/State/Country) before passing it into JS.

Map container#

Leaflet map is rendered inside:
<div id="map-{{ id }}">
Fixed heights:
mobile: h-[265px]
desktop: lg:h-[440px]

Loading state#

The section is rendered with the map--loading modifier class. While it is present, the component's headings, text and controls are covered by skeleton placeholders (%skeleton-cover), so the layout is stable before images, fonts and scripts finish loading.
initComponent removes the class on the next animation frame after Alpine initialises the component; it does not wait for the window load event.
See Theme Classes for the shared skeleton styles.
Modified at 2026-10-15 13:49:16
Previous
Login
Next
NavBar
Built with