One of the most powerful use cases for the Places Autocomplete component is to simplify address entry in forms. This example demonstrates how to capture the detailed address data from a user's selection and use it to automatically populate the fields of a checkout form.
Begin typing an address in the search box. After selecting a suggestion, the form fields below will be automatically filled with the corresponding address components.
The key to this functionality is fetching and parsing the `addressComponents` array provided by the Google Places API.
Here is the complete code for the checkout form example. You can adapt this logic to fit the specific fields your own forms require.
<script lang="ts">
import { PlaceAutocomplete } from 'places-autocomplete-svelte';
import type { PlaceResult, ComponentOptions } from 'places-autocomplete-svelte/interfaces';
let { data } = $props();
const PUBLIC_GOOGLE_MAPS_API_KEY = data?.PUBLIC_GOOGLE_MAPS_API_KEY;
// --- Form State ---
// Use $state to create a reactive object for our form fields
let form = $state({
street_number: '',
route: '', // Street name
locality: '', // City
administrative_area_level_1: '', // State/Province
country: '',
postal_code: ''
});
// --- Component State ---
let placesError = $state('');
let fullResponse: PlaceResult | null = $state(null);
// --- Component Configuration ---
const fetchFields = ['addressComponents', 'formattedAddress'];
// Set clear_input: false to keep the address visible after selection.
const options: ComponentOptions = {
placeholder: 'Start typing your address...',
clear_input: false
};
// --- Event Handlers ---
const onError = (error: string) => (placesError = error);
const onResponse = (response: PlaceResult) => {
fullResponse = response;
// Reset form fields before populating
for (const key in form) {
form[key as keyof typeof form] = '';
}
// Helper function to find a specific address component
const getAddressComponent = (type: string) =>
response.addressComponents?.find((c) => c.types.includes(type))?.longText || '';
// Populate the form state with values from the response
form.street_number = getAddressComponent('street_number');
form.route = getAddressComponent('route');
form.locality = getAddressComponent('postal_town') || getAddressComponent('locality');
form.administrative_area_level_1 = getAddressComponent('administrative_area_level_1');
form.country = getAddressComponent('country');
form.postal_code = getAddressComponent('postal_code');
};
</script>
{#if placesError}
<div class="mt-4 rounded-md bg-red-100 p-4 text-red-800">
<p class="font-semibold text-red-800">Error</p>
<p>{placesError}</p>
</div>
{/if}
<PlaceAutocomplete
{PUBLIC_GOOGLE_MAPS_API_KEY}
{options}
{onError}
{onResponse}
/>
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
<div class="mx-auto w-full max-w-md">
<label for="address1" class="block text-sm font-medium text-slate-200">Address:</label>
<input
type="text"
id="address1"
class="mt-2 block w-full rounded-md border border-gray-300 bg-slate-700 p-2 text-slate-300"
bind:value={obj.street_number}
/>
</div>
<div class="mx-auto w-full max-w-md">
<label for="city" class="block text-sm font-medium text-slate-200">City:</label>
<input
id="city"
class="mt-2 block w-full rounded-md border border-gray-300 bg-slate-700 p-2 text-slate-300"
bind:value={obj.locality}
/>
</div>
<div class="mx-auto w-full max-w-md">
<label for="postcode" class="block text-sm font-medium text-slate-200">Postal Code:</label>
<input
type="text"
id="postcode"
class="mt-2 block w-full rounded-md border border-gray-300 bg-slate-700 p-2 text-slate-300"
bind:value={obj.postal_code}
/>
</div>
<div class="mx-auto w-full max-w-md">
<label for="country" class="block text-sm font-medium text-slate-200">Country:</label>
<input
type="text"
id="country"
class="mt-2 block w-full rounded-md border border-gray-300 bg-slate-700 p-2 text-slate-300"
bind:value={obj.country}
/>
</div>
</div>