Laravel Mapcn
Toggle sidebar

Clusters

Docs / Clusters

Overview

The <x-map-cluster-layer> component efficiently handles large numbers of markers by grouping them into clusters. As you zoom in, clusters break apart into individual points. This is the recommended approach for datasets with hundreds or thousands of points.

For large datasets, always prefer <x-map-cluster-layer> over individual <x-map-marker> tags to maintain high frame rates.

Basic Usage

Pass an array of GeoJSON Features to the :data prop. Click on clusters to zoom in:

From GeoJSON URL

Instead of passing an array, you can point to a remote GeoJSON file. MapLibre will fetch and cluster the data client-side:

Custom Cluster Color

Change the cluster circle color to match your brand:

Data Format

The :data prop accepts an array of GeoJSON Feature objects. Each feature must have:

php
[
    'type' => 'Feature',
    'properties' => [
        'name' => 'Location Name',   // Any properties you want
    ],
    'geometry' => [
        'type' => 'Point',
        'coordinates' => [$lng, $lat],  // [longitude, latitude]
    ],
]
Remember that GeoJSON uses [longitude, latitude] order, not [latitude, longitude] — this is a common source of bugs.

Props

PropTypeDefaultDescription
:dataarray[]GeoJSON Features or raw items
url?stringnullURL to GeoJSON file (client-side fetch)
id?stringnullUnique ID for events/updates
:cluster-max-zoomint14Max zoom level to cluster at
:cluster-radiusint50Pixel radius to group points
:cluster-min-pointsint2Min points to form a cluster
cluster-colorstring'#1A56DB'Color of the cluster circle
cluster-text-colorstring'#FFFFFF'Color of the count text
:cluster-size-stopsarray[[0, 30], [100, 40], [1000, 50]]Circle radius based on point count
point-colorstring'#1A56DB'Color of unclustered point
:point-radiusint6Radius of unclustered point
:show-countbooltrueShow point count in clusters
popup-property?stringnullProperty to show in popup
popup-template?stringnullInline HTML popup template
:click-zoombooltrueZoom in on cluster click
:bufferint256Tile buffer
:tolerancefloat0.5Simplification tolerance
:max-features-to-inlineint2000Max features to pass via props
classstring''Additional CSS classes

Point Popups

Customize the popup shown when clicking unclustered points.

Using the Popup Slot

The recommended approach is using the popup slot. Use {property} placeholders for dynamic data:

blade
<x-map-cluster-layer :data="$locations">
    <x-slot:popup>
        <div class="p-3">
            <h3 class="font-bold">{name}</h3>
            <p class="text-xs">{address}</p>
            <p class="text-[10px] text-gray-400 mt-2">{lat}, {lng}</p>
        </div>
    </x-slot:popup>
</x-map-cluster-layer>

Priority Order

  1. Slot Control: <x-slot:popup>
  2. Inline Template: popup-template="..." attribute
  3. Property Card: popup-property="name" attribute
  4. Default: Auto-detected name/label property

Dynamic Data Updates

Update cluster data without a full Livewire re-render by dispatching a map event from your PHP component. Each cluster layer listens for its unique ID:

php
$this->dispatch("map:update-cluster-data-{$clusterId}",
    \Kwasii\LivewireMapcn\Support\GeoJSON::fromArray($filteredData)
);