A lightweight and framework-safe Alpine.js directive for integrating Google Maps Places Autocomplete into your frontend, with:
- ✅ Works with Alpine.js 3+
- ✅ Google Places API address lookup
- ✅ Minimal setup and configuration
- ✅ Structured address output (line_1, city, state, zip, country, coordinates)
- ✅ Full support for
<dialog>elements and modals (prevents dropdown clipping) - ✅ Automatic cleanup of event listeners and observers
- ✅ Handles async Google Maps API loading with timeout fallback
N.B.: It relies on google.maps.places.Autocomplete
As of March 1st, 2025, google.maps.places.Autocomplete is not available to new customers. Please use google.maps.places.PlaceAutocompleteElement instead. At this time, google.maps.places.Autocomplete is not scheduled to be discontinued, but google.maps.places.PlaceAutocompleteElement is recommended over google.maps.places.Autocomplete. While google.maps.places.Autocomplete will continue to receive bug fixes for any major regressions, existing bugs in google.maps.places.Autocomplete will not be addressed. At least 12 months notice will be given before support is discontinued. Please see https://developers.google.com/maps/legacy for additional details and https://developers.google.com/maps/documentation/javascript/places-migration-overview for the migration guide
If you are fine with it, let's go 🚀
✅ You have an API key that has been provided access to (1) Maps JavaScript API and (2) Places API
✅ alpinejs: ^3.0
npm install @binary-cats/alpinejs-google-autocompleteInclude the Maps JS loader and fire maps:init once it’s ready:
<script>googleMapsReady = () => {document.dispatchEvent(new Event('maps:init'))}</script>
<script async src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&loading=async&libraries=places&callback=googleMapsReady"></script>In your bundle, assuming app.js:
import Alpine from 'alpinejs'
import googleAddressLookup from '@binary-cats/alpinejs-google-autocomplete'
Alpine.plugin(googleAddressLookup)
Alpine.start()Finally, in your HTML:
<div x-data="{address:{}}">
<input
x-address-lookup="address"
type="text"
autocomplete="off"
placeholder="Search for an address..."/>
</div>The directive automatically handles <dialog> elements to prevent the autocomplete dropdown from being clipped:
<dialog x-data="{address:{}}">
<input
x-address-lookup="address"
type="text"
autocomplete="off"
placeholder="Search for an address..."/>
</dialog>Once a place is selected, it will populate the address object with:
{
line_1: '123 Main St',
city: 'New York',
state: 'NY',
zip: '10001',
country: 'United States',
google_location_id: 'ChIJ...',
formatted_address: '123 Main St, New York, NY 10001',
lat: 40.7128,
lng: -74.0060
}line_1: Street number and route (e.g., "123 Main St")city: Locality namestate: State abbreviation (short_name)zip: Postal codecountry: Country namegoogle_location_id: Google Place IDformatted_address: Full formatted address stringlat: Latitude coordinatelng: Longitude coordinate
Run the test suite:
npm testRun tests in watch mode:
npm run test:watchGenerate coverage report:
npm run test:coverageThe test suite uses Vitest with comprehensive coverage of all functionality.
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
You're free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.
This package works in all modern browsers that support:
- ES6 modules
- Alpine.js 3.x
- Google Maps JavaScript API
The MIT License (MIT). Please see License File for more information.
