A React hook for Google Places Autocomplete API
npm install places-autocomplete-hookA lightweight React hook for Google Places Autocomplete API that provides a simple way to implement location search functionality in your React applications.


> This package is a wrapper around the Google Places Autocomplete API. Make sure you have a valid Google Places API key with the Places API enabled in your Google Cloud Console.

- ๐ Real-time address suggestions as you type
- ๐ฏ Support for location biasing
- ๐ Multi-language support
- โก Debounced search to prevent excessive API calls
- ๐ Session token support for billing optimization
- ๐ Detailed place information retrieval with formattedAddress
- ๐จ Fully customizable UI (bring your own components)
- ๐งช Fully tested with Vitest
``bash`
npm install places-autocomplete-hookor
yarn add places-autocomplete-hook
`tsx
import { usePlacesAutocomplete } from 'places-autocomplete-hook';
function AddressInput() {
const {
value,
suggestions,
setValue,
clearSuggestions,
loading,
error,
getPlaceDetails,
handlePlaceSelect,
} = usePlacesAutocomplete({
apiKey: 'YOUR_GOOGLE_PLACES_API_KEY',
});
const handleSelect = async (placeId: string) => {
await handlePlaceSelect(placeId);
const details = await getPlaceDetails(placeId);
console.log('Selected place:', details.formattedAddress);
};
return (
API Reference
$3
`typescript
interface UsePlacesAutocompleteOptions {
/* Your Google Places API key /
apiKey: string;
/* Debounce time in milliseconds (default: 300) /
debounceMs?: number;
/* Language code for results (default: 'en') /
language?: string;
/* Primary place types to include (Google Places API v1) /
includedPrimaryTypes?: string[];
/* Region codes to restrict results to (ISO 3166-1 alpha-2 country codes) /
includedRegionCodes?: string[];
/* Session token for billing optimization /
sessionToken?: string;
/* Location bias for more relevant results /
location?: {
lat: number;
lng: number;
radius?: number;
};
/* Callback that is called when a place is selected, providing the place ID /
setSelectedPlace?: (placeId: string) => void;
}
`$3
`typescript
interface UsePlacesAutocompleteResult {
/* Current input value /
value: string;
/* Suggestions state and data /
suggestions: {
status: 'OK' | 'ZERO_RESULTS' | 'ERROR' | 'LOADING';
data: PlacePrediction[];
};
/* Function to update the input value /
setValue: (value: string, shouldFetchData?: boolean) => void;
/* Function to clear suggestions /
clearSuggestions: () => void;
/* Function to manually trigger a search /
search: (input: string) => Promise;
/* Loading state /
loading: boolean;
/* Error state /
error: Error | null;
/* Function to get detailed place information /
getPlaceDetails: (placeId: string, fields?: string[]) => Promise;
/* Function to handle place selection /
handlePlaceSelect: (placeId: string) => Promise;
}
`$3
`typescript
interface PlacePrediction {
place: string;
placeId: string;
text: {
text: string;
matches: Array<{
endOffset: number;
}>;
};
structuredFormat: {
mainText: {
text: string;
matches: Array<{
endOffset: number;
}>;
};
secondaryText: {
text: string;
};
};
types: string[];
}interface PlaceDetails {
placeId: string;
formattedAddress: string;
addressComponents: AddressComponent[];
location: {
latitude: number;
longitude: number;
};
streetNumber?: string;
streetName?: string;
city?: string;
state?: string;
country?: string;
postalCode?: string;
}
`Advanced Usage
$3
`tsx
const { value, suggestions, setValue } = usePlacesAutocomplete({
apiKey: 'YOUR_API_KEY',
location: {
lat: 37.7749,
lng: -122.4194,
radius: 50000, // 50km radius
},
});
`$3
`tsx
const { value, suggestions, setValue } = usePlacesAutocomplete({
apiKey: 'YOUR_API_KEY',
// Restrict to specific primary place types (Places API v1)
includedPrimaryTypes: ['locality', 'sublocality'],
});
`#### Available Primary Types
The
includedPrimaryTypes parameter (Places API v1) accepts an array of primary place types:-
'locality' - Cites, Countries
- 'administrative_area_level_3' - Third-level administrative areas
- 'administrative_area_level_4' - Fourth-level administrative areas
- 'administrative_area_level_5' - Fifth-level administrative areas
- 'administrative_area_level_6' - Sixth-level administrative areas
- 'administrative_area_level_7' - Seventh-level administrative areas
- 'archipelago' - Groups of islands
- 'colloquial_area' - Colloquial or informal areas
- 'continent' - Continental regions
- 'establishment' - Businesses and establishments
- 'finance' - Financial institutions
- 'food' - Food-related establishments
- 'general_contractor' - General contracting services
- 'geocode' - Geocoding results
- 'health' - Health-related establishments
- 'intersection' - Street intersections
- 'landmark' - Notable landmarks
- 'natural_feature' - Natural geographical features
- 'neighborhood' - Neighborhoods and districts
- 'place_of_worship' - Religious buildings
- 'plus_code' - Plus codes for locations
- 'point_of_interest' - Points of interest
- 'political' - Political boundaries
- 'postal_code_prefix' - Postal code prefixes
- 'postal_code_suffix' - Postal code suffixes
- 'postal_town' - Postal towns
- 'premise' - Named locations
- 'route' - Streets, roads, etc.
- 'street_address' - Specific street addresses
- 'sublocality' - Districts, neighborhoods, etc.
- 'sublocality_level_1' - First-level sublocalities
- 'sublocality_level_2' - Second-level sublocalities
- 'sublocality_level_3' - Third-level sublocalities
- 'sublocality_level_4' - Fourth-level sublocalities
- 'sublocality_level_5' - Fifth-level sublocalities
- 'subpremise' - Unit numbers, apartment numbers, etc.
- 'town_square' - Town squares and plazas$3
`tsx
const { value, suggestions, setValue } = usePlacesAutocomplete({
apiKey: 'YOUR_API_KEY',
// Restrict results to specific countries/regions
includedRegionCodes: ['US', 'CA'], // North America only
});
`#### Available Region Codes
The
includedRegionCodes parameter accepts an array of ISO 3166-1 alpha-2 country codes:-
'US' - United States
- 'CA' - Canada
- 'GB' - United Kingdom
- 'DE' - Germany
- 'FR' - France
- 'AU' - Australia
- 'JP' - Japan
- 'IN' - India
- 'BR' - Brazil
- 'MX' - Mexico
- 'ES' - Spain
- 'IT' - Italy
- 'NL' - Netherlands
- 'SE' - Sweden
- 'NO' - Norway
- 'DK' - Denmark
- 'FI' - Finland
- 'CH' - Switzerland
- 'AT' - Austria
- 'BE' - Belgium#### Common Use Cases
- Single country:
['US'] - Restrict to United States only
- Multiple countries: ['US', 'CA'] - North America
- European Union: ['DE', 'FR', 'IT', 'ES', 'NL'] - Major EU countries
- German-speaking regions: ['DE', 'AT', 'CH'] - Germany, Austria, Switzerland
- Nordic countries: ['SE', 'NO', 'DK', 'FI'] - Scandinavia and Finland$3
`tsx
const { value, suggestions, setValue } = usePlacesAutocomplete({
apiKey: 'YOUR_API_KEY',
sessionToken: 'YOUR_SESSION_TOKEN',
});
`$3
`tsx
const { getPlaceDetails, handlePlaceSelect } = usePlacesAutocomplete({
apiKey: 'YOUR_API_KEY',
});const handleSelect = async (placeId: string) => {
await handlePlaceSelect(placeId);
const details = await getPlaceDetails(placeId);
console.log('Full address:', details.formattedAddress);
console.log('City:', details.city);
console.log('State:', details.state);
console.log('Country:', details.country);
console.log('Coordinates:', details.location);
};
`$3
You can specify which fields to retrieve when getting place details:
`tsx
const details = await getPlaceDetails(placeId, [
'formattedAddress',
'addressComponents',
'location',
'displayName',
'photos',
'rating',
'userRatingCount',
'priceLevel',
'types',
'websiteUri',
'phoneNumbers',
'businessStatus',
'openingHours',
'delivery',
'dineIn',
'takeout',
'reservable',
'servesBeer',
'outdoorSeating',
'liveMusic',
'menuForChildren',
'servesCocktails',
'servesDessert',
'servesCoffee',
'goodForChildren',
'allowsDogs',
'restroom',
'parking',
'paymentOptions',
'accessibilityOptions',
'atmosphere',
'crowd',
'childrenFriendly',
'touristFriendly',
'upscale',
'casual',
'trendy',
'romantic',
'intimate',
'classy',
'hipster',
'divey',
'touristy',
'local',
'familyFriendly',
'groups',
]);
`$3
#### This should not be used in production since it will cost a lot.
You can use
* wildcard to retrieve all available fields when getting place details:`tsx
const details = await getPlaceDetails(placeId, ['*']);
`Development
This project uses Yarn as the package manager. Make sure you have Yarn installed before setting up the project locally.
`bash
Install dependencies
yarn installRun tests
yarn testBuild the project
yarn buildRun in development mode
yarn dev
`Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Note: This project requires Yarn for development. Please use
yarn instead of npm` when working on this project locally.MIT Seatsmatch GmbH