Examples & Recipes

Practical examples and code patterns for common use cases with Places Autocomplete JS.

Quick Navigation

Checkout Form Integration

Automatically populate form fields with structured address components from a selected place.

const autocomplete = new PlacesAutocomplete({
  containerId: 'shipping-address',
  googleMapsApiKey: 'YOUR_API_KEY',
  fetchFields: ['formattedAddress', 'addressComponents'],
  onResponse: (placeDetails) => {
    // Populate form fields from address components
    const components = placeDetails.addressComponents || [];
    
    const getComponent = (type) => {
      const comp = components.find(c => c.types.includes(type));
      return comp ? comp.longText : '';
    };
    
    document.getElementById('street').value = 
      getComponent('street_number') + ' ' + getComponent('route');
    document.getElementById('city').value = getComponent('locality');
    document.getElementById('state').value = 
      getComponent('administrative_area_level_1');
    document.getElementById('zip').value = getComponent('postal_code');
    document.getElementById('country').value = getComponent('country');
  },
  options: {
    placeholder: 'Enter shipping address...',
    clear_input: false
  }
});
					
				

Tip: Set clear_input: false to keep the full address visible in the input field after selection.

Dynamic Country Filtering

Update the autocomplete region and language based on a country dropdown selection.

const countrySelect = document.getElementById('country-select');
const autocomplete = new PlacesAutocomplete({
  containerId: 'autocomplete-container',
  googleMapsApiKey: 'YOUR_API_KEY',
  requestParams: {
    includedRegionCodes: ['US']
  }
});

// Update region when country changes
countrySelect.addEventListener('change', (e) => {
  const countryCode = e.target.value;
  autocomplete.setRequestParams({
    includedRegionCodes: [countryCode],
    region: countryCode,
    language: getLanguageForCountry(countryCode)
  });
  autocomplete.clear();
});

function getLanguageForCountry(code) {
  const languageMap = {
    'US': 'en-US',
    'GB': 'en-GB',
    'FR': 'fr',
    'DE': 'de',
    'ES': 'es'
  };
  return languageMap[code] || 'en';
}
					
				

Note: Calling clear() after updating parameters ensures a fresh session token is generated for the new region.

Geolocation Biasing

Use the browser's geolocation API to bias results toward the user's current location.

// Request user's current location
if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(
    (position) => {
      const userLocation = {
        lat: position.coords.latitude,
        lng: position.coords.longitude
      };
      
      const autocomplete = new PlacesAutocomplete({
        containerId: 'autocomplete-container',
        googleMapsApiKey: 'YOUR_API_KEY',
        requestParams: {
          origin: userLocation,
          locationBias: {
            lat: 53.39670653190076,
            lng: -2.9346197562747967,
            radius: 50000 // 50km radius
          }
        },
        options: {
          distance: true,
          distance_units: 'miles'
        }
      });
    },
    (error) => {
      console.error('Geolocation error:', error);
      // Initialize without location bias
      new PlacesAutocomplete({
        containerId: 'autocomplete-container',
        googleMapsApiKey: 'YOUR_API_KEY'
      });
    }
  );
}
					
				

Privacy: Always request user permission before accessing geolocation. Provide a fallback for users who deny permission.

Multi-Step Forms

Manage autocomplete instances across multiple form steps with proper cleanup.

let currentAutocomplete = null;
let formData = {
  billingAddress: null,
  shippingAddress: null
};

function initialiseStep(step) {
  // Clean up previous instance
  if (currentAutocomplete) {
    currentAutocomplete.destroy();
  }
  
  const containerId = step === 1 ? 'billing-address' : 'shipping-address';
  
  currentAutocomplete = new PlacesAutocomplete({
    containerId: containerId,
    googleMapsApiKey: 'YOUR_API_KEY',
    onResponse: (placeDetails) => {
      if (step === 1) {
        formData.billingAddress = placeDetails;
      } else {
        formData.shippingAddress = placeDetails;
      }
      
      // Enable next button
      document.getElementById('next-btn').disabled = false;
    },
    options: {
      autofocus: true
    }
  });
}

// Initialize first step
initialiseStep(1);

// Handle step navigation
document.getElementById('next-btn').addEventListener('click', () => {
  const currentStep = getCurrentStep();
  if (currentStep === 1) {
    showStep(2);
    initialiseStep(2);
  } else {
    submitForm(formData);
  }
});
					
				

Important: Always call destroy() before creating a new instance to prevent memory leaks and event listener duplication.

Error Handling

Implement robust error handling with user-friendly messages for different error scenarios.

const autocomplete = new PlacesAutocomplete({
  containerId: 'autocomplete-container',
  googleMapsApiKey: 'YOUR_API_KEY',
  onResponse: (placeDetails) => {
    // Clear any previous errors
    hideError();
    
    // Validate the response
    if (!placeDetails.addressComponents) {
      showError('Unable to retrieve full address details. Please try again.');
      return;
    }
    
    // Process the place details
    processAddress(placeDetails);
  },
  onError: (error) => {
    console.error('Autocomplete error:', error);
    
    // Handle specific error types
    if (error.message?.includes('ZERO_RESULTS')) {
      showError('No results found. Please try a different search term.');
    } else if (error.message?.includes('OVER_QUERY_LIMIT')) {
      showError('Service temporarily unavailable. Please try again later.');
    } else if (error.message?.includes('REQUEST_DENIED')) {
      showError('Service configuration error. Please contact support.');
    } else {
      showError('An error occurred. Please try again.');
    }
  }
});

function showError(message) {
  const errorDiv = document.getElementById('error-message');
  errorDiv.textContent = message;
  errorDiv.classList.remove('hidden');
}

function hideError() {
  document.getElementById('error-message').classList.add('hidden');
}
					
				

Retain Input Value After Selection

Keep the selected address visible in the input field instead of clearing it.

const autocomplete = new PlacesAutocomplete({
  containerId: 'autocomplete-container',
  googleMapsApiKey: 'YOUR_API_KEY',
  options: {
    clear_input: false, // Keep the address in the input field
    placeholder: 'Enter your address...'
  },
  onResponse: (placeDetails) => {
    // The input field will now show the formattedAddress
    console.log('Selected:', placeDetails.formattedAddress);
    
    // You can still access the full details
    console.log('Full details:', placeDetails);
  }
});
					
				

Single Page Application (SPA) Integration

Properly manage component lifecycle in SPAs to prevent memory leaks.

// app.js or routing file
class AddressComponent {
  constructor(containerId, apiKey) {
    this.containerId = containerId;
    this.apiKey = apiKey;
    this.autocomplete = null;
  }
  
  mount() {
    this.autocomplete = new PlacesAutocomplete({
      containerId: this.containerId,
      googleMapsApiKey: this.apiKey,
      onResponse: (placeDetails) => {
        this.handlePlaceSelection(placeDetails);
      }
    });
  }
  
  unmount() {
    if (this.autocomplete) {
      this.autocomplete.destroy();
      this.autocomplete = null;
    }
  }
  
  handlePlaceSelection(placeDetails) {
    // Emit event or update state
    this.onPlaceSelected?.(placeDetails);
  }
}

// Usage with routing
const router = {
  '/checkout': {
    onEnter: () => {
      const addressComponent = new AddressComponent(
        'address-input',
        'YOUR_API_KEY'
      );
      addressComponent.mount();
      
      // Store reference for cleanup
      window.currentComponents = { addressComponent };
    },
    onLeave: () => {
      window.currentComponents?.addressComponent?.unmount();
    }
  }
};
					
				

Critical: Always clean up instances when navigating away from views to prevent memory leaks and duplicate event listeners.

More Examples

Check out additional working examples in the main examples section: