Map Integration

A powerful feature is integrating the autocomplete search with a live Google Map. This example demonstrates how to initialise a map and have it automatically pan and place a marker at the location selected by the user.

Live Demo

Search for a location in the input below. When you select a place, the map will center on it and display a marker.

powered by
powered by Google

How It Works

This integration relies on dynamically loading the Google Maps libraries and then using the component's `onResponse` event to interact with the map instance.

  1. Dynamic Library Loading: Inside the `onMount` lifecycle hook, we use the `importLibrary()` helper to asynchronously load the `maps` and `marker` libraries. This is crucial because these libraries can only be accessed after the main Google Maps script has been initialised.
  2. Map Initialisation: Once the libraries are loaded, we create a new `google.maps.Map` instance, attaching it to a `
    ` element on the page using Svelte's `bind:this` directive.
  3. Handling the Response: The `onResponse` event handler receives the full `PlaceResult` object. We check for the `location` property, which contains the geographic coordinates.
  4. Updating the Map and Marker: We use `map.setCenter()` to pan the map to the new coordinates. We then either create a new `AdvancedMarkerElement` or update the `position` of the existing marker to reflect the selected location.

Full Code Example

Here is the complete code for this example. Remember to replace `'YOUR_MAP_ID'` with your own ID from the Google Cloud Console.

<script>
import { onMount } from 'svelte';
import { browser } from '$app/environment';
import { PlaceAutocomplete } from 'places-autocomplete-svelte';
import { initialiseGMaps, setGMapsContext, importLibrary } from 'places-autocomplete-svelte/gmaps';
import type {PlaceResult,ComponentOptions } from 'places-autocomplete-svelte/interfaces';

let { data } = $props();
const PUBLIC_GOOGLE_MAPS_API_KEY = data?.PUBLIC_GOOGLE_MAPS_API_KEY;
const fetchFields = ['formattedAddress', 'addressComponents', 'location'];

// 1. Set the context for Google Maps. This should be done in the script's top-level scope.
setGMapsContext();

// 2. If we are in the browser, trigger the asynchronous loading process.
if (browser) {
	initialiseGMaps({
		key: PUBLIC_GOOGLE_MAPS_API_KEY,
		v: 'weekly' 
	}).catch((error: any) => {
		// ... handle error (already logged in initialiseGMaps)
	});
}

// 3. Define the types for the libraries you will load.
type LoadedLibraries = {
	Map: typeof google.maps.Map;
	AdvancedMarkerElement: typeof google.maps.marker.AdvancedMarkerElement;
};

/**
 * Install the Type Definitions for Google Maps
 * npm install --save-dev @types/google.maps
 */
let mapElement: HTMLElement;
let map: google.maps.Map;
let marker: google.maps.marker.AdvancedMarkerElement;
let loadedLibs: LoadedLibraries | undefined;


// Error handling
const onError = (error: string) => {
	console.error('Places Autocomplete Error:', error);
};

// Response handler
const onResponse = (response: PlaceResult) => {
	if (response.location) {
		map.setCenter(response.location);
		map.setZoom(15);
		if (marker) {
			marker.position = response.location;
		} else {
			if (loadedLibs) {
				marker = new loadedLibs.AdvancedMarkerElement({
					position: response.location,
					map: map,
					title: response.formattedAddress || 'Selected Location'
				});
			}
		}
	}
};

/**
 * 4. Load the Google Maps JavaScript API and the required libraries on component mount.
 */
onMount(async () => {

	const { Map } = await importLibrary('maps');
	const { AdvancedMarkerElement } = await importLibrary('marker');
	loadedLibs = { Map, AdvancedMarkerElement };

	const mapEl = document.getElementById('map');
	// Check if the element was found before using it
	if (mapEl && loadedLibs.Map) {
		mapElement = mapEl; // This is now safe
		map = new loadedLibs.Map(mapElement, {
			center: { lat: 51.5072, lng: -0.1276 }, // Default to London
			zoom: 10,
			mapId: 'your-map-id'
		});
	} else {
		// It's good practice to log an error if the element is missing
		console.error('Failed to find the map element with ID "map"');
	}
});

</script>

<PlaceAutocomplete {onError} {onResponse} {fetchFields} />

<div id="map" class="h-96 w-full rounded-md"></div>

2025 Places Autocomplete Svelte.