sm breakpoint, 4 from md)Default view has no embedded map; each card links to Google Maps instead. For an interactive map, use the WithMap view.{
"name": "Stores",
"view": "Default",
"section": "SectionA",
"settings": {
"header": "Our stores",
"alignment": "Left",
"body": "<p>Sample text</p>",
"groups": [
{
"title": "Sample title",
"stores": [
{
"name": "Sample text",
"address": {
"address1": "Sample text",
"address2": "",
"city": "Sample text",
"state": "Sample text",
"country": "",
"postalCode": "",
"translation": {}
},
"phone": "Sample text",
"email": "sample@example.com",
"workingHours": "<p>Sample text</p>",
"url": "https://example.com/store",
"image": {
"link": "https://example.com/media/store.jpg",
"alt": "Sample text"
},
"imageTranslation": {}
},
"..."
]
},
"..."
],
"id": "Component Id",
"section": "SectionA",
"type": "NoirStores",
"name": "Stores",
"configuredInContentApi": true,
"view": "Default",
"displayName": "",
"cssClass": ""
},
"translations": {
"searchPlaceholder": "Sample text",
"allGroups": "Sample text",
"noStoresFound": "Sample text",
"...": "..."
}
}settings.idsettings.header — rendered as the component heading.settings.alignment — Left (default), Center or Right; applies to the header and description.settings.body — description, rendered as HTML (Markdown is converted on the server).settings.cssClasssettings.groups[]GlobalData.Company.Address (if present)translations.NoStoresAvailableimage, address, phone, workingHours (HTML), url. Empty values are hidden.translations.*| Key | Used for |
|---|---|
SearchPlaceholder | Search input placeholder and label |
FilterByGroup | Accessible label of the group dropdown |
AllGroups | The “all groups” option of the dropdown |
Result / Results | Results count label (singular / plural) |
Website | Link to the store's url |
ViewOnMap | Google Maps link |
NoStoresFound | No store matches the search or filter |
MainStore | Heading of the fallback company address |
NoStoresAvailable | No groups and no company address |
settings.alignment.<select>) only when there is more than one distinct group title; its first option shows all groupstel: link), email (mailto: link), working hours, website link and a Google Maps search link built from the store name and address (address1, postalCode, city, state, country)GlobalData.Company.Address.*, or NoStoresAvailable.StoresStructuredData reusable (Schema.org ItemList of LocalBusiness) for every configured store.Components/Stores/Default.js exposes:<section x-data='storesdefault.initComponent(groups)'>groups (each with title and stores), searchQuery and selectedGroup.md breakpoint (64rem); below it each titled group becomes an accordion with one group open at a time. A new search or group filter opens the first matching group.applyFilters() runs once on init and again whenever searchQuery or selectedGroup changes. It stores in matches, for each group (by position), a Set of the indexes of the stores that pass the group filter and the search, and updates resultsCount:selectedGroup keeps only groups with that title (empty means all groups).searchQuery keeps a whole group when its title matches, otherwise only the stores whose name, address, postal code, city or country matches.normalize); the searchable text is normalized once on init.x-show on the server-rendered groups and cards.NFD normalization.Reusables/StoresStructuredData--loading modifier class is applied.Components/Stores/WithMap.liquid renders the same server-rendered directory as Default (search, group filter, accordion and cards behave identically) plus an interactive Google map of the stores.MapsApiKey (GlobalData.Settings.MapsApiKey), with the Maps JavaScript API enabled and your storefront domains allowed as HTTP referrers.MapsMapId (GlobalData.Settings.MapsMapId), created in the same Google Cloud project as the key. The map uses Advanced Markers, which Google only draws on a map with a Map ID.MapKeyMissing is shown; the list still works.latitude and longitude on each store. Stores without coordinates stay in the list but get no marker. When no store has coordinates, Google Maps is not loaded at all and the list takes the full width.https://shop.example.com/*); under API restrictions allow only Maps JavaScript API.MapsApiKey setting.MapsMapId setting.settings.markerLink.link — optional image shown inside a theme-coloured badge instead of Google's default pin.settings.zoom — zoom used when one store is shown or selected (default 15). Fitting several stores never zooms in further than this.{
"view": "WithMap",
"settings": {
"markerLink": { "link": "https://example.com/media/marker.png" },
"zoom": 15,
"groups": [
{
"title": "Sample title",
"stores": [
{ "name": "Sample text", "latitude": "37.983810", "longitude": "23.727539", "...": "..." }
]
}
]
}
}| Key | Used for |
|---|---|
Nearest | Button that shows the store nearest to the shopper |
ViewDirections | Directions link in the marker popup |
LocationUnavailable | The shopper's location could not be determined |
MapUnavailable | The map failed to load |
MapKeyMissing | MapsApiKey or MapsMapId is not configured |
loading=async, in the page language) and @googlemaps/markerclusterer only when the key and Map ID are set and at least one store has coordinates. When the component is on a page more than once, both scripts are loaded only once and shared.Nearest asks for the shopper's location, fits the map to the shopper and the nearest store, and opens that store's popup.gm_authFailure) or times out after 10 seconds, MapUnavailable is shown in place of the map and the list remains usable.Components/Stores/WithMap.js exposes storeswithmap.initComponent(groups, mapRequested, websiteLabel, directionsLabel, locationUnavailableLabel, markerLink, zoom, mapId).@googlemaps/markerclusterer 2.5.3 (unpkg, with SRI)Reusables/StoresStructuredData