Api

<ScriptGoogleMapsMarkerClusterer>

Groups nearby markers into clusters for cleaner map visualization at lower zoom levels. Place inside a <ScriptGoogleMaps> component.

optionsOmit<MarkerClustererOptions, 'map'>

Configuration options for the marker clusterer.

Installation

Requires the @googlemaps/markerclusterer peer dependency:

pnpm add @googlemaps/markerclusterer

Usage

Child markers register and unregister themselves automatically. No manual marker management required.

<script setup lang="ts">
const locations = ref([
  { id: 1, name: 'Sydney Opera House', position: { lat: -33.8568, lng: 151.2153 } },
  { id: 2, name: 'Bondi Beach', position: { lat: -33.8908, lng: 151.2743 } },
  { id: 3, name: 'Taronga Zoo', position: { lat: -33.8433, lng: 151.2411 } },
])
</script>

<template>
  <ScriptGoogleMaps api-key="your-api-key" :center="{ lat: -33.86, lng: 151.24 }" :zoom="12">
    <ScriptGoogleMapsMarkerClusterer>
      <ScriptGoogleMapsMarker
        v-for="location in locations"
        :key="location.id"
        :position="location.position"
      >
        <ScriptGoogleMapsInfoWindow>
          <div>{{ location.name }}</div>
        </ScriptGoogleMapsInfoWindow>
      </ScriptGoogleMapsMarker>
    </ScriptGoogleMapsMarkerClusterer>
  </ScriptGoogleMaps>
</template>

Dynamic Markers

Markers added or removed reactively (e.g., via v-for with a changing list) automatically register with and unregister from the clusterer.

<script setup lang="ts">
const locations = ref([/* initial locations */])

function addLocation(position: google.maps.LatLngLiteral) {
  locations.value.push({ id: Date.now(), name: 'New', position })
}
</script>

<template>
  <ScriptGoogleMaps api-key="your-api-key">
    <ScriptGoogleMapsMarkerClusterer>
      <ScriptGoogleMapsMarker
        v-for="loc in locations"
        :key="loc.id"
        :position="loc.position"
      />
    </ScriptGoogleMapsMarkerClusterer>
  </ScriptGoogleMaps>
</template>

Custom Algorithm

Pass algorithm through options to customize clustering behavior. See the @googlemaps/markerclusterer documentation for available algorithms.

<script setup lang="ts">
import { SuperClusterAlgorithm } from '@googlemaps/markerclusterer'

const clustererOptions = {
  algorithm: new SuperClusterAlgorithm({ radius: 200 }),
}
</script>

<template>
  <ScriptGoogleMaps api-key="your-api-key">
    <ScriptGoogleMapsMarkerClusterer :options="clustererOptions">
      <ScriptGoogleMapsMarker
        v-for="loc in locations"
        :key="loc.id"
        :position="loc.position"
      />
    </ScriptGoogleMapsMarkerClusterer>
  </ScriptGoogleMaps>
</template>

Custom Cluster Renderer

Use the #renderer slot to customize how clusters look using Vue templates. The slot receives cluster (with count, position, markers), stats, and map (the Google Maps instance).

<template>
  <ScriptGoogleMaps api-key="your-api-key">
    <ScriptGoogleMapsMarkerClusterer>
      <template #renderer="{ cluster }">
        <div
          style="
            background: #4285f4;
            color: white;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: bold;
          "
        >
          {{ cluster.count }}
        </div>
      </template>

      <ScriptGoogleMapsMarker
        v-for="loc in locations"
        :key="loc.id"
        :position="loc.position"
      />
    </ScriptGoogleMapsMarkerClusterer>
  </ScriptGoogleMaps>
</template>

The #renderer slot overrides the renderer option. Each cluster gets its own AdvancedMarkerElement with the slot content as its visual.

The clusterer only renders its default slot after the clusterer instance is ready. This prevents child markers from mounting before the clusterer can receive them.