A customizable React Native TextInput component for Google Places Autocomplete using the Places API (New)
- Fully customizable UI
- Debounced search
- Clear button (x)
- Loading indicator
- Keyboard-aware
- Custom place types filtering
- RTL support
- Multi-language support
- TypeScript support
- Session token support for reduced billing costs
- Extended place details fetching (Optional)
![]() |
npm install react-native-google-places-textinput
# or
yarn add react-native-google-places-textinput
-
Enable the Places API (New) in your Google Cloud Project
- This component specifically requires the new
Places API (New)
, not the legacyPlaces API
- In the Google Cloud Console, go to
APIs & Services
>Library
and search for "Places API (New)"
- This component specifically requires the new
-
Create an API key
- Go to "APIs & Services" > "Credentials" and create a new API key
- Under "API restrictions", make sure "Places API (New)" is selected
import GooglePlacesTextInput from 'react-native-google-places-textinput';
const YourComponent = () => {
const handlePlaceSelect = (place) => {
console.log('Selected place:', place);
};
const basicStyles = {
container: {
width: '100%', // Ensure full width
paddingHorizontal: 16,
},
input: {
height: 40, // Comfortable touch target
}
};
return (
<GooglePlacesTextInput
apiKey="YOUR_GOOGLE_PLACES_API_KEY"
onPlaceSelect={handlePlaceSelect}
style={basicStyles}
/>
);
};
Example with Places API Configuration
const ConfiguredExample = () => {
const handlePlaceSelect = (place) => {
console.log('Selected place:', place);
};
return (
<GooglePlacesTextInput
apiKey="YOUR_GOOGLE_PLACES_API_KEY"
onPlaceSelect={handlePlaceSelect}
languageCode="fr"
types={['restaurant', 'cafe']}
includedRegionCodes={['fr', 'be']}
minCharsToFetch={2}
/>
);
};
Example with Full Styling
const StyledExample = () => {
const handlePlaceSelect = (place) => {
console.log('Selected place:', place);
};
const customStyles = {
container: {
width: '100%',
marginHorizontal: 0,
},
input: {
height: 45,
borderColor: '#ccc',
borderRadius: 8,
},
suggestionsContainer: {
backgroundColor: '#ffffff',
maxHeight: 250,
},
suggestionItem: {
padding: 15,
},
suggestionText: {
main: {
fontSize: 16,
color: '#333',
},
secondary: {
fontSize: 14,
color: '#666',
}
},
loadingIndicator: {
color: '#999',
},
placeholder: {
color: '#999',
}
};
return (
<GooglePlacesTextInput
apiKey="YOUR_GOOGLE_PLACES_API_KEY"
placeHolderText="Search for a place"
onPlaceSelect={handlePlaceSelect}
style={customStyles}
/>
);
};
Example Using Session Token
import { useRef } from 'react';
const SessionTokenExample = () => {
const inputRef = useRef(null);
const handlePlaceSelect = (place, sessionToken) => {
console.log('Selected place:', place);
console.log('Session token used:', sessionToken);
// You can now use this same sessionToken when fetching place details
// to benefit from reduced billing (session matching)
fetchPlaceDetails(place.placeId, sessionToken);
};
const fetchPlaceDetails = async (placeId, sessionToken) => {
// Your code to fetch place details using the same sessionToken
// ...
};
return (
<GooglePlacesTextInput
ref={inputRef}
apiKey="YOUR_GOOGLE_PLACES_API_KEY"
onPlaceSelect={handlePlaceSelect}
/>
);
};
Example with Place Details Fetching
const PlaceDetailsExample = () => {
const handlePlaceSelect = (place) => {
console.log('Selected place:', place);
// Access detailed place information
if (place.details) {
console.log('Address components:', place.details.addressComponents);
console.log('Geometry:', place.details.geometry);
console.log('Photos:', place.details.photos);
// And other fields you requested
}
};
const handleError = (error) => {
console.error('API error:', error);
};
return (
<GooglePlacesTextInput
apiKey="YOUR_GOOGLE_PLACES_API_KEY"
onPlaceSelect={handlePlaceSelect}
onError={handleError}
fetchDetails={true}
detailsFields={[
'address_components',
'formatted_address',
'geometry',
'viewport',
'photos',
'place_id',
'types'
]}
/>
);
};
Prop | Type | Required | Default | Description |
---|---|---|---|---|
Essential Props | ||||
apiKey | string | Yes | - | Your Google Places API key |
Input Configuration | ||||
value | string | No | '' | Initial input value |
placeHolderText | string | No | - | Placeholder text for input |
minCharsToFetch | number | No | 1 | Minimum characters before fetching |
debounceDelay | number | No | 200 | Delay before triggering search |
Places API Configuration | ||||
proxyUrl | string | No | - | Custom proxy URL for Places API requests |
languageCode | string | No | - | Language code (e.g., 'en', 'fr') |
includedRegionCodes | string[] | No | - | Array of region codes to filter results |
types | string[] | No | [] | Array of place types to filter |
biasPrefixText | string | No | - | Text to prepend to search query |
Place Details Configuration | ||||
fetchDetails | boolean | No | false | Automatically fetch place details when a place is selected |
detailsProxyUrl | string | No | null | Custom proxy URL for place details requests |
detailsFields | string[] | No | [] | Array of fields to include in the place details response |
UI Customization | ||||
style | StyleProp | No | {} | Custom styles object |
showLoadingIndicator | boolean | No | true | Show/hide loading indicator |
showClearButton | boolean | No | true | Show/hide the input clear button |
forceRTL | boolean | No | undefined | Force RTL layout direction |
hideOnKeyboardDismiss | boolean | No | false | Hide suggestions when keyboard is dismissed |
Event Handlers | ||||
onPlaceSelect | (place: Place | null, sessionToken?: string) => void | Yes | - | Callback when place is selected |
onTextChange | (text: string) => void | No | - | Callback triggered on text input changes |
onError | (error: any) => void | No | - | Callback for handling API errors |
You can automatically fetch detailed place information when a user selects a place suggestion by enabling the fetchDetails
prop:
<GooglePlacesTextInput
apiKey="YOUR_GOOGLE_PLACES_API_KEY"
fetchDetails={true}
detailsFields={['formatted_address', 'geometry', 'viewport', 'photos']}
onPlaceSelect={(place) => console.log(place.details)}
/>
When fetchDetails
is enabled:
- The component fetches place details immediately when a user selects a place suggestion
- The details are attached to the place object passed to your
onPlaceSelect
callback in thedetails
property - Use the
detailsFields
prop to specify which fields to include in the response, reducing API costs
For a complete list of available fields, see the Place Details API documentation.
This component automatically manages session tokens to optimize your Google Places API billing:
- A session token is generated when the component mounts
- The same token is automatically used for all autocomplete requests and place details requests
- The component automatically resets tokens after place selection, input clearing, or calling
clear()
Note: This automatic session token management ensures Google treats your autocomplete and details requests as part of the same session, reducing your billing costs with no additional configuration needed.
The component exposes the following methods through refs:
clear()
: Clears the input and suggestionsfocus()
: Focuses the input fieldgetSessionToken()
: Returns the current session token
const inputRef = useRef(null);
// Usage
inputRef.current?.clear();
inputRef.current?.focus();
const token = inputRef.current?.getSessionToken();
The component accepts a style
prop with the following structure:
type Styles = {
container?: ViewStyle;
input?: TextStyle;
suggestionsContainer?: ViewStyle;
suggestionItem?: ViewStyle;
suggestionText?: {
main?: TextStyle;
secondary?: TextStyle;
};
loadingIndicator?: {
color?: string;
};
placeholder?: {
color?: string;
};
}
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
Written by Amit Palomo
Made with create-react-native-library