Geolocation Bias

Providing location-aware search results creates a personalised user experience. This example demonstrates how to request the user's current location using the browser's Geolocation API and use it to bias autocomplete suggestions towards nearby places—perfect for "near me" features and local discovery applications.

Live Demo

Click "Use My Location" to allow browser access to your coordinates. The autocomplete will then prioritise places near you, with distance calculations shown in the results.

Location Status

○ Not Set

Using default location (London) for search results

powered by
powered by Google

How It Works

Geolocation bias combines browser APIs with Google Places to create personalised search experiences:

  1. Request Permission: Use the browser's navigator.geolocation.getCurrentPosition() API to request the user's coordinates. This triggers a permission prompt on first use.
  2. Handle Success: When permission is granted, extract the latitude and longitude from position.coords. Store these coordinates in your component state.
  3. Apply Location Bias: Update requestParams.locationBias with a circular area centred on the user's coordinates. This tells the API to favour nearby results.
  4. Set Origin Point: Also set requestParams.origin to the user's location. This enables accurate distance calculations shown with the distance: true option.
  5. Handle Errors: Provide clear feedback if location access is denied, unavailable, or times out. Always include a fallback location (e.g., city centre) for graceful degradation.
  6. Respect Privacy: Only request location when necessary, explain why it's needed, and allow users to opt out. Cache positions using maximumAge to avoid repeated prompts.

📍 Privacy & Best Practices

  • Explain the benefit: Tell users why you need their location ("Show nearby restaurants").
  • Make it optional: Never require location access—provide manual alternatives.
  • HTTPS required: Geolocation only works on secure connections (except localhost).
  • Cache wisely: Use maximumAge to avoid constant re-prompts, but refresh for accuracy when needed.
  • Handle denials gracefully: If denied, explain how to enable it or proceed without location data.

Full Code Example

Here's a complete implementation with error handling and fallback behaviour:

<script lang="ts">
	import { browser } from '$app/environment';
	import { PlaceAutocomplete } from 'places-autocomplete-svelte';
	import type { PlaceResult } from 'places-autocomplete-svelte/interfaces';

	let userLocation: { lat: number; lng: number } | null = $state(null);
	let componentKey = $state({});

	// Request geolocation on component mount
	const requestGeolocation = () => {
		if (!browser || !navigator.geolocation) return;

		navigator.geolocation.getCurrentPosition(
			(position) => {
				userLocation = {
					lat: position.coords.latitude,
					lng: position.coords.longitude
				};

				// Update params with user's location
				requestParams = {
					...requestParams,
					locationBias: {
						circle: {
							center: userLocation,
							radius: 10000 // 10km
						}
					},
					origin: userLocation
				};

				componentKey = {}; // Re-initialise component
			},
			(error) => {
				console.error('Geolocation error:', error.message);
			},
			{
				enableHighAccuracy: false,
				timeout: 10000,
				maximumAge: 300000 // Cache for 5 minutes
			}
		);
	};

	// Reactive request params
	let requestParams = $state({
		language: 'en-gb',
		region: 'GB',
		locationBias: userLocation ? {
			circle: {
				center: userLocation,
				radius: 10000
			}
		} : undefined,
		origin: userLocation || { lat: 51.5074, lng: -0.1278 } // Fallback
	});

	const onResponse = (response: PlaceResult) => {
		console.log('Selected place:', response);
	};
</script>

<!-- Request location access -->
<button onclick={requestGeolocation}>
	Use My Location
</button>

{#if userLocation}
	<p>Searching near: {userLocation.lat.toFixed(4)}, {userLocation.lng.toFixed(4)}</p>
{/if}

<!-- Component with geolocation bias -->
{#key componentKey}
	<PlaceAutocomplete
		{onResponse}
		{requestParams}
		options={{ 
			placeholder: userLocation ? 'Search near you...' : 'Search...',
			distance: true 
		}}
	/>
{/key}