Home

Awesome

<a href="https://www.npmjs.com/package/react-native-google-places-autocomplete"> <img alt="npm version" src="https://img.shields.io/npm/v/react-native-google-places-autocomplete"/> </a>

Google Maps Search Component for React Native

Customizable Google Places autocomplete component for iOS and Android React-Native apps

Sponsor

<p align="center"> <br/> <a href="https://bit.ly/3rneTTI" target="_blank"> <img src="https://raw.githubusercontent.com/FaridSafi/react-native-google-places-autocomplete/master/Assets/expensify-logo.png"> </a> <br> <p align="center"> The financial management super app for expenses, corporate cards, and more. </p> <a href="https://bit.ly/3rneTTI" target="_blank"> <p align="center"> Click to learn more </p> </a> </p>

Preview

Installation

Step 1.

npm install react-native-google-places-autocomplete --save

or

yarn add react-native-google-places-autocomplete

Step 2.

Get your Google Places API keys and enable "Google Places API Web Service" (NOT Android or iOS) in the console. Billing must be enabled on the account.

Step 3.

Enable "Google Maps Geocoding API" if you want to use GoogleReverseGeocoding for Current Location

Basic Example

Basic Address Search

import React from 'react';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';

const GooglePlacesInput = () => {
  return (
    <GooglePlacesAutocomplete
      placeholder='Search'
      onPress={(data, details = null) => {
        // 'details' is provided when fetchDetails = true
        console.log(data, details);
      }}
      query={{
        key: 'YOUR API KEY',
        language: 'en',
      }}
    />
  );
};

export default GooglePlacesInput;

You can also try the basic example in a snack here

More Examples

Get Current Location

<details> <summary>Click to expand</summary>

Extra step required!

If you are targeting React Native 0.60.0+ you must install either @react-native-community/geolocation (link) or react-native-geolocation-service(link).

Please make sure you follow the installation instructions there and add navigator.geolocation = require(GEOLOCATION_PACKAGE) somewhere in you application before <GooglePlacesAutocomplete />.

import React from 'react';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';

// navigator.geolocation = require('@react-native-community/geolocation');
// navigator.geolocation = require('react-native-geolocation-service');

const GooglePlacesInput = () => {
  return (
    <GooglePlacesAutocomplete
      placeholder='Search'
      onPress={(data, details = null) => {
        // 'details' is provided when fetchDetails = true
        console.log(data, details);
      }}
      query={{
        key: 'YOUR API KEY',
        language: 'en',
      }}
      currentLocation={true}
      currentLocationLabel='Current location'
    />
  );
};

export default GooglePlacesInput;
</details>

Search with predefined option

<details> <summary>Click to expand</summary>
import React from 'react';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';

const homePlace = {
  description: 'Home',
  geometry: { location: { lat: 48.8152937, lng: 2.4597668 } },
};
const workPlace = {
  description: 'Work',
  geometry: { location: { lat: 48.8496818, lng: 2.2940881 } },
};

const GooglePlacesInput = () => {
  return (
    <GooglePlacesAutocomplete
      placeholder='Search'
      onPress={(data, details = null) => {
        // 'details' is provided when fetchDetails = true
        console.log(data, details);
      }}
      query={{
        key: 'YOUR API KEY',
        language: 'en',
      }}
      predefinedPlaces={[homePlace, workPlace]}
    />
  );
};

export default GooglePlacesInput;
</details>

Limit results to one country

<details> <summary>Click to expand</summary>
import React from 'react';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';

const GooglePlacesInput = () => {
  return (
    <GooglePlacesAutocomplete
      placeholder='Search'
      onPress={(data, details = null) => {
        // 'details' is provided when fetchDetails = true
        console.log(data, details);
      }}
      query={{
        key: 'YOUR API KEY',
        language: 'en',
        components: 'country:us',
      }}
    />
  );
};

export default GooglePlacesInput;
</details>

Use a custom Text Input Component

<details> <summary>Click to expand</summary>

This is an example using the Text Input from react-native-elements.

import React from 'react';
import { Text, View, Image } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
import { Input } from 'react-native-elements';

const GOOGLE_PLACES_API_KEY = 'YOUR_GOOGLE_API_KEY';

const GooglePlacesInput = () => {
  return (
    <GooglePlacesAutocomplete
      query={{
        key: GOOGLE_PLACES_API_KEY,
        language: 'en', // language of the results
      }}
      onPress={(data, details) => console.log(data, details)}
      textInputProps={{
        InputComp: Input,
        leftIcon: { type: 'font-awesome', name: 'chevron-left' },
        errorStyle: { color: 'red' },
      }}
    />
  );
};

export default GooglePlacesInput;
</details>

Props

This list is a work in progress. PRs welcome!

Prop Nametypedescriptiondefault valueOptions
autoFillOnNotFoundbooleandisplays the result from autocomplete if the place details api return not foundfalsetrue | false
currentLocationbooleanWill add a 'Current location' button at the top of the predefined places listfalsetrue | false
currentLocationLabelstringchange the display label for the current location buttonCurrent LocationAny string
debouncenumberdebounce the requests (in ms)0
disableScrollbooleandisable scroll on the results list
enableHighAccuracyLocationbooleanuse GPS or not. If set to true, a GPS position will be requested. If set to false, a WIFI location will be requested. use GPS or not. If set to true, a GPS position will be requested. If set to false, a WIFI location will be requested.true
enablePoweredByContainerbooleanshow "powered by Google" at the bottom of the search results listtrue
fetchDetailsbooleanget more place details about the selected option from the Place Details APIfalse
filterReverseGeocodingByTypesarrayfilter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
GooglePlacesDetailsQueryobject"query" object for the Google Place Details API (when you press on a suggestion)
GooglePlacesSearchQueryobject"query" object for the Google Places Nearby API (when you use current location to find nearby places){ rankby: 'distance', type: 'restaurant' }
GoogleReverseGeocodingQueryobject"query" object for the Google Geocode API (when you use current location to get the current address)
isRowScrollablebooleanenable/disable horizontal scrolling of a list result https://reactnative.dev/docs/scrollview#scrollenabledtrue
inbetweenCompoReact.ReactNodeInsert a ReactNode in between the search bar and the search results Flatlist
keepResultsAfterBlurbooleanshow list of results after blurfalsetrue | false
keyboardShouldPersistTapsstringDetermines when the keyboard should stay visible after a tap https://reactnative.dev/docs/scrollview#keyboardshouldpersisttaps'always''never' | 'always' | 'handled'
listEmptyComponentfunctionuse FlatList's ListEmptyComponent prop when no autocomplete results are found.
listLoaderComponentfunctionshow this component while results are loading.
listHoverColorstringunderlay color of the list result when hovered (web only)'#ececec'
listUnderlayColorstringunderlay color of the list result when pressed https://reactnative.dev/docs/touchablehighlight#underlaycolor'#c8c7cc'
listViewDisplayedstringoverride the default behavior of showing the list (results) view'auto''auto' | true | false
minLengthnumberminimum length of text to trigger a search0
nearbyPlacesAPIstringwhich API to use for current location'GooglePlacesSearch''none' | 'GooglePlacesSearch' | 'GoogleReverseGeocoding'
numberOfLinesnumbernumber of lines (android - multiline must be set to true) https://reactnative.dev/docs/textinput#numberoflines1
onFailfunctionreturns if an unspecified error comes back from the API
onNotFoundfunctionreturns if the Google Places Details API returns a 'not found' code (when you press a suggestion).
onPressfunctionreturns when after a suggestion is selected
onTimeoutfunctioncallback when a request timeout()=>console.warn('google places autocomplete: request timeout')
placeholderstringplaceholder text https://reactnative.dev/docs/textinput#placeholder'Search'
predefinedPlacesarrayAllows you to show pre-defined places (e.g. home, work)
predefinedPlacesAlwaysVisiblebooleanShows predefined places at the top of the search resultsfalse
preProcessfunctiondo something to the text of the search input before a search request is sent
queryobject"query" object for the Google Places Autocomplete API (link){ key: 'missing api key', language: 'en', types: 'geocode' }
renderDescriptionfunctiondetermines the data passed to each renderRow (search result)
renderHeaderComponentfunctionuse the ListHeaderComponent from FlatList when showing autocomplete results
renderLeftButtonfunctionadd a component to the left side of the Text Input
renderRightButtonfunctionadd a component to the right side of the Text Input
renderRowfunctioncustom component to render each result row (use this to show an icon beside each result). data and index will be passed as input parameters
requestUrlobjectused to set the request url for the library
returnKeyTypestringthe return key text https://reactnative.dev/docs/textinput#returnkeytype'search'
stylesobjectSee styles section below
suppressDefaultStylesbooleanremoves all default styling from the libraryfalsetrue | false
textInputHidebooleanHide the Search inputfalsetrue | false
textInputPropsobjectdefine props for the textInput, or provide a custom input component
timeoutnumberhow many ms until the request will timeout20000

Methods

method nametypedescription
getAddressText() => stringreturn the value of TextInput
setAddressText(value: string) => voidset the value of TextInput
focusvoidmakes the TextInput focus
blurvoidmakes the TextInput lose focus
clearvoidremoves all text from the TextInput
isFocused() => booleanreturns true if the TextInput is currently focused; false otherwise
getCurrentLocation() => voidmakes a query to find nearby places based on current location

You can access these methods using a ref.

Example

import React, { useEffect, useRef } from 'react';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';

const GooglePlacesInput = () => {
  const ref = useRef();

  useEffect(() => {
    ref.current?.setAddressText('Some Text');
  }, []);

  return (
    <GooglePlacesAutocomplete
      ref={ref}
      placeholder='Search'
      onPress={(data, details = null) => {
        // 'details' is provided when fetchDetails = true
        console.log(data, details);
      }}
      query={{
        key: 'YOUR API KEY',
        language: 'en',
      }}
    />
  );
};

export default GooglePlacesInput;

Styling

GooglePlacesAutocomplete can be easily customized to meet styles of your app. Pass styles props to GooglePlacesAutocomplete with style object for different elements (keys for style object are listed below)

keytype
containerobject (View)
textInputContainerobject (View style)
textInputobject (style)
listViewobject (ListView style)
rowobject (View style)
loaderobject (View style)
descriptionobject (Text style)
predefinedPlacesDescriptionobject (Text style)
separatorobject (View style)
poweredContainerobject (View style)
poweredobject (Image style)

Example

<GooglePlacesAutocomplete
  placeholder='Enter Location'
  minLength={2}
  autoFocus={false}
  returnKeyType={'default'}
  fetchDetails={true}
  styles={{
    textInputContainer: {
      backgroundColor: 'grey',
    },
    textInput: {
      height: 38,
      color: '#5d5d5d',
      fontSize: 16,
    },
    predefinedPlacesDescription: {
      color: '#1faadb',
    },
  }}
/>

Default Styles

{
  container: {
    flex: 1,
  },
  textInputContainer: {
    flexDirection: 'row',
  },
  textInput: {
    backgroundColor: '#FFFFFF',
    height: 44,
    borderRadius: 5,
    paddingVertical: 5,
    paddingHorizontal: 10,
    fontSize: 15,
    flex: 1,
  },
  poweredContainer: {
    justifyContent: 'flex-end',
    alignItems: 'center',
    borderBottomRightRadius: 5,
    borderBottomLeftRadius: 5,
    borderColor: '#c8c7cc',
    borderTopWidth: 0.5,
  },
  powered: {},
  listView: {},
  row: {
    backgroundColor: '#FFFFFF',
    padding: 13,
    height: 44,
    flexDirection: 'row',
  },
  separator: {
    height: 0.5,
    backgroundColor: '#c8c7cc',
  },
  description: {},
  loader: {
    flexDirection: 'row',
    justifyContent: 'flex-end',
    height: 20,
  },
}

Web Support

Web support can be enabled via the requestUrl prop, by passing in a URL that you can use to proxy your requests. CORS implemented by the Google Places API prevent using this library directly on the web. You will need to use a proxy server. Please be mindful of this limitation when opening an issue.

The requestUrl prop takes an object with two required properties: useOnPlatform and url, and an optional headers property.

The url property is used to set the url that requests will be made to. If you are using the regular google maps API, you need to make sure you are ultimately hitting https://maps.googleapis.com/maps/api.

useOnPlatform configures when the proxy url is used. It can be set to either web- will be used only when the device platform is detected as web (but not iOS or Android, or all - will always be used.

You can optionally specify headers to apply to your request in the headers object.

Example:

import React from 'react';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';

const GooglePlacesInput = () => {
  return (
    <GooglePlacesAutocomplete
      placeholder='Search'
      onPress={(data, details = null) => {
        // 'details' is provided when fetchDetails = true
        console.log(data, details);
      }}
      query={{
        key: 'YOUR API KEY',
        language: 'en',
      }}
      requestUrl={{
        useOnPlatform: 'web', // or "all"
        url:
          'https://cors-anywhere.herokuapp.com/https://maps.googleapis.com/maps/api', // or any proxy server that hits https://maps.googleapis.com/maps/api
        headers: {
          Authorization: `an auth token`, // if required for your proxy
        },
      }}
    />
  );
};

export default GooglePlacesInput;

Note: The library expects the same response that the Google Maps API would return.

Features

Compatibility

This library does not use the iOS, Android or JS SDKs from Google. This comes with some Pros and Cons.

Pros:

Cons:

Use Inside a <ScrollView/> or <FlatList/>

If you need to include this component inside a ScrolView or FlatList, remember to apply the keyboardShouldPersistTaps attribute to all ancestors ScrollView or FlatList (see this issue comment).

A word about the Google Maps APIs

Google Provides a bunch of web APIs for finding an address or place, and getting it’s details. There are the Google Places Web APIs (Place Search, Place Details, Place Photos, Place Autocomplete, Query Autocomplete) and the Google Geocode API .

The 5 Google Places Web APIs are:

The Geocoding API allows you to convert an address into geographic coordinates (lat, long) and to "reverse geocode", which is the process of converting geographic coordinates into a human-readable address.

Which APIs does this library use?

Place Autocomplete API, Place Details API, Place Search API and the Geocoding API.

We use the Place Autocomplete API to get suggestions as you type. When you click on a suggestion, we use the Place Details API to get more information about the place.

We use the Geocoding API and the Place Search API to use your current location to get results.

Because the query parameters are different for each API, there are 4 different "query" props.

  1. Autocomplete -> query (options)
  2. Place Details -> GooglePlacesDetailsQuery (options)
  3. Nearby Search -> GooglePlacesSearchQuery (options)
  4. Geocode -> GoogleReverseGeocodingQuery (options)

Number 1 is used while getting autocomplete results.
Number 2 is used when you click on a result.
Number 3 is used when you select 'Current Location' to load nearby results.
Number 4 is used when nearbyPlacesAPI='GoogleReverseGeocoding' is set and you select 'Current Location' to load nearby results.

Changelog

Please see the releases tab for the changelog information.

License

MIT

Authors