Maps

A maps component that supports Leaflet and OpenLayers providers with clean separation between UI configuration and map data. Uses external JSON files for map content, making it ideal for complex maps with many markers while keeping page frontmatter minimal.

Leaflet

Choose Leaflet when you need:

  • Smaller file size (lighter weight at ~145KB)
  • Simpler API for basic mapping needs
  • Faster initial load time
  • Large plugin ecosystem
  • Mobile-first design with touch interactions
  • Better performance on older devices

OpenLayers

Choose OpenLayers when you need:

  • Advanced vector capabilities and data visualization
  • Support for various data formats (GeoJSON, KML, GPX, WMS)
  • Custom map projections and coordinate systems
  • Complex interactions and custom controls
  • Better performance with large datasets
  • Enterprise-grade mapping features

Marker Configuration

Each marker in the JSON data file's markers array includes:

{
  "latitude": 40.7128,
  "longitude": -74.0060,
  "title": "Location Name",
  "icon": "star",
  "content": {
    "title": "Popup Heading",
    "body": "Description text for the popup",
    "link": "https://example.com"
  }
}

Marker Properties:

  • latitude/longitude: Marker position coordinates (required)
  • title: Tooltip text displayed on hover
  • icon: Optional icon name from the built-in icon registry
  • content: Popup content object
    • title: Popup heading text
    • body: Description or details
    • link: Optional external URL for "Read more" functionality

Available Icons for Markers

The maps component includes a built-in icon registry with commonly used marker icons:

  • map-pin: Default location marker
  • home: House/residence marker
  • camera: Photo location marker
  • coffee: Cafe/restaurant marker
  • briefcase: Business/office marker
  • shopping-bag: Shopping/retail marker
  • star: Featured/important location
  • heart: Favorite/loved location
  • calendar: Event location marker
  • clock: Time-sensitive location
  • music: Entertainment venue marker
  • phone: Contact/service location

If no icon is specified, the default red location pin marker is used.

Performance & Implementation

JSON Data Architecture: Map content is stored in external JSON files in /lib/data/maps/, keeping page frontmatter clean while supporting complex datasets with many markers.

Dynamic Loading: The component loads the appropriate mapping library (Leaflet v1.9.4 or OpenLayers v10.3.0) from CDN only when needed. This keeps your initial bundle size small.

Provider Switching: You can easily switch between Leaflet and OpenLayers by changing just the mapProvider field. The same JSON data file works with both providers.

Data Reusability: The same JSON data file can be referenced by multiple pages, making it easy to maintain consistent map content across your site.

Build-time Icon Registry: Icons are automatically scanned from JSON files and included in the build only when used, optimizing bundle size.

Multiple Maps: You can have multiple maps on the same page using different providers and different JSON data files. Each map maintains its own state and configuration.

Consistent SVG Markers: Both providers use the same custom SVG marker design for visual consistency across all maps.

Responsive Design: Maps automatically adapt to their container width and include mobile-optimized touch interactions.

Accessibility: Markers include proper title attributes for screen readers, and all external links include appropriate security attributes.

Advanced Feature

Marker Clustering

Handle Large Datasets

When displaying many markers, clustering groups nearby markers together to improve performance and visual clarity. Click clusters to zoom in and expand them.

Loading interactive map, please wait... Loading map...

Clustering Configuration

For maps with many markers, clustering groups nearby markers together to improve performance and reduce visual clutter. Clustering works with both Leaflet and OpenLayers providers.

Clustering Properties:

PropertyTypeDefaultDescription
enabledbooleanfalseEnable/disable clustering
maxZoomnumber15Zoom level beyond which clustering is disabled
radiusnumber50Cluster radius in pixels for grouping markers
minClusterSizenumber2Minimum markers required to form a cluster
style.backgroundColorstring'#4285f4'Cluster background color
style.textColorstring'#ffffff'Text color for marker count
style.borderColorstring'#1976d2'Cluster border color
style.borderWidthnumber2Border width in pixels

Clustering Code Example:

Page frontmatter:

- sectionType: maps
  mapProvider: 'openlayers'
  mapData: 'nyc-clustering-demo'

JSON data file (lib/data/maps/nyc-clustering-demo.json):

{
  "latitude": 40.7128,
  "longitude": -74.0060,
  "zoom": 8,
  "clustering": {
    "enabled": true,
    "maxZoom": 15,
    "radius": 60,
    "minClusterSize": 2,
    "style": {
      "backgroundColor": "#e74c3c",
      "textColor": "#ffffff",
      "borderColor": "#c0392b",
      "borderWidth": 2
    }
  },
  "markers": [
    {
      "latitude": 40.7128,
      "longitude": -74.0060,
      "title": "Manhattan",
      "icon": "star",
      "content": {
        "title": "Manhattan",
        "body": "The heart of New York City"
      }
    }
  ]
}

When clustering is enabled, markers within the specified radius are grouped together and displayed as numbered cluster markers. Clicking a cluster will zoom in to reveal individual markers, or expand the cluster if at maximum zoom level.

Configuration

- sectionType: maps
  containerTag: section

  mapProvider: 'leaflet' # 'leaflet' or 'openlayers'
  mapData: 'london-landmarks' # references lib/data/maps/london-landmarks.json
  height: '500px' # optional custom height (defaults to 400px)

  text:
    leadIn: 'Interactive Mapping'
    title: Explore London Landmarks
    titleTag: 'h2'
    subTitle: 'Discover famous locations across the city'
    prose: Interactive maps provide engaging ways to showcase locations, whether for business directories, travel guides, or event venues...
  ctas:
    - url: 'https://leafletjs.com'
      label: 'Learn More'
      isButton: true
      buttonStyle: 'primary'

Notes

  • Dynamic library loading, custom SVG markers, interactive popups, marker clustering
  • Responsive design across all devices with accessibility features for screen readers
  • Multiple maps per page with independent configurations and provider selection
  • All text fields and CTAs are optional
  • Maps automatically adapt to container dimensions

Page Frontmatter (UI Configuration):

PropertyTypeDescription
mapProviderstringMap library to use ('leaflet' or 'openlayers')
mapDatastringReference to JSON file in lib/data/maps/ (e.g., 'london-landmarks')
heightstringOptional custom map height (e.g., '500px', '50vh') - defaults to 400px
textobjectStandard text block with leadIn, title, subtitle, and prose
ctasarrayArray of call-to-action buttons or links

JSON Data File (Map Content):

PropertyTypeDescription
latitude/longitudenumberMap center coordinates
zoomnumberInitial zoom level
clusteringobjectOptional clustering configuration object
markersarrayArray of marker objects with coordinates and popup content

JSON Data Structure

Map data is stored in /lib/data/maps/{mapData}.json files with the following structure:

{
  "latitude": 51.509865,
  "longitude": -0.118092,
  "zoom": 10,
  "clustering": {
    "enabled": true,
    "maxZoom": 15,
    "radius": 50,
    "minClusterSize": 2,
    "style": {
      "backgroundColor": "#4285f4",
      "textColor": "#ffffff",
      "borderColor": "#1976d2",
      "borderWidth": 2
    }
  },
  "markers": [
    {
      "latitude": 51.509865,
      "longitude": -0.118092,
      "title": "London",
      "icon": "star",
      "content": {
        "title": "London",
        "body": "Description text...",
        "link": "https://example.com"
      }
    }
  ]
}