Guides

Programmatic API

The ScriptGoogleMaps component exposes its internal APIs via template ref, giving you full control beyond what the declarative SFC components provide.

Accessing the API

<script setup lang="ts">
const mapRef = ref()

function onReady({ googleMaps, map, createAdvancedMapMarker, resolveQueryToLatLng, importLibrary }) {
  // All APIs available here
}
</script>

<template>
  <ScriptGoogleMaps ref="mapRef" @ready="onReady" />
</template>

Exposed Properties

PropertyTypeDescription
googleMapsRef<typeof google.maps>The Google Maps API namespace
mapShallowRef<google.maps.Map>The map instance
createAdvancedMapMarker(options?) => Promise<AdvancedMarkerElement>Create a marker programmatically
resolveQueryToLatLng(query: string) => Promise<LatLng>Geocode a location string
importLibrary(key: string) => Promise<any>Load an additional Google Maps library

Creating Markers Programmatically

For cases where declarative v-for markers aren't flexible enough (dynamic data, imperative creation logic), use createAdvancedMapMarker:

<script setup lang="ts">
const mapRef = ref()

async function addMarkerAtCenter() {
  const map = mapRef.value.map.value
  const center = map.getCenter()
  const marker = await mapRef.value.createAdvancedMapMarker({
    position: { lat: center.lat(), lng: center.lng() },
    title: 'New Marker',
  })
}
</script>

<template>
  <ScriptGoogleMaps ref="mapRef" :center="{ lat: -33.8688, lng: 151.2093 }" :zoom="12" />
  <button @click="addMarkerAtCenter">
    Add Marker at Center
  </button>
</template>
For most use cases, prefer the declarative ScriptGoogleMapsAdvancedMarkerElement component with v-for. Use the programmatic API when you need fine-grained control over marker lifecycle or are integrating with external data sources.

Geocoding Queries

Convert location strings to coordinates using resolveQueryToLatLng. When you enable the registry proxy, this resolves server-side (cheaper, API key hidden). Otherwise it falls back to the client-side Places API.

<script setup lang="ts">
const mapRef = ref()

async function goToLocation(query: string) {
  const latLng = await mapRef.value.resolveQueryToLatLng(query)
  mapRef.value.map.value.setCenter(latLng)
  mapRef.value.map.value.setZoom(15)
}
</script>

<template>
  <ScriptGoogleMaps ref="mapRef" :center="{ lat: 0, lng: 0 }" :zoom="2" />
  <button @click="goToLocation('Eiffel Tower, Paris')">
    Go to Paris
  </button>
</template>

Importing Libraries

Google Maps splits functionality into libraries that load on demand. Use importLibrary to access geometry, drawing, places, and visualization APIs:

<script setup lang="ts">
const mapRef = ref()

async function measureDistance(a: google.maps.LatLng, b: google.maps.LatLng) {
  const geometry = await mapRef.value.importLibrary('geometry')
  return geometry.spherical.computeDistanceBetween(a, b)
}
</script>

Available libraries: marker, places, geometry, drawing, visualization

Subscribing to Map Events

Use the @ready event to access the map instance and subscribe to native Google Maps events:

<script setup lang="ts">
function onReady({ map }) {
  watch(map, (m) => {
    if (!m)
      return
    m.addListener('zoom_changed', () => {
      console.log('Zoom:', m.getZoom())
    })
    m.addListener('center_changed', () => {
      console.log('Center:', m.getCenter()?.toJSON())
    })
    m.addListener('idle', () => {
      // Map finished moving, good time to fetch data for visible bounds
      const bounds = m.getBounds()
    })
  }, { immediate: true })
}
</script>

<template>
  <ScriptGoogleMaps @ready="onReady" />
</template>