**European Economic Area (EEA) developers**

> [!NOTE]
> If your billing address is in the European Economic Area, effective on 8 July 2025, the [Google Maps Platform EEA Terms of Service](https://cloud.google.com/terms/maps-platform/eea) will apply to your use of the Services. Functionality varies by region. [Learn more](https://developers.google.com/maps/comms/eea/faq.md.txt).

The Place Autocomplete Widget creates a text input field, supplies place
predictions in a UI pick list, and returns place details in response to the
user's selection. Use the Place Autocomplete Widget to embed a complete
self-contained autocomplete user interface on your web page. For the complete
API reference, see
[`PlaceAutocompleteElement`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElement).
<iframe src="https://maps-docs-team.web.app/samples/place-autocomplete-map/dist/" allow="fullscreen; fullscreen"></iframe>

## Prerequisites

To use Place Autocomplete, you must enable Places API (New) on your Google Cloud
project. See [Get started](https://developers.google.com/maps/documentation/javascript/place-get-started.md.txt)
for details.

## What's new

Place Autocomplete has been improved in the following ways:

- The Autocomplete widget UI supports regional localization (including RTL languages), for the text input placeholder, predictions list logo, and the place predictions.
- Enhanced accessibility, including support for screen readers and keyboard interaction.
- The Autocomplete widget returns the new [Place class](https://developers.google.com/maps/documentation/javascript/place.md.txt) ([`Place`](https://developers.google.com/maps/documentation/javascript/reference/place.md.txt#Place) reference) to simplify handling of the returned object.
- Better support for mobile devices and small screens.
- Better performance and improved graphical appearance.

## Add an Autocomplete widget

The Autocomplete widget creates a text input field, supplies place
predictions in a UI pick list, and returns place details in response to a user
click using the
[`gmp-select`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElement.gmp-select)
listener. This section shows you how to add an autocomplete widget to a web
page or a Google map.

### Add an Autocomplete widget to a web page

To add the Autocomplete widget to a web page, create a new
[`google.maps.places.PlaceAutocompleteElement`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElement),
and append it to the page as shown in the following example:

### TypeScript

```typescript
// Request needed libraries.
const { PlaceAutocompleteElement } =
    await google.maps.importLibrary('places');
// Create the input HTML element, and append it.
const placeAutocomplete = new PlaceAutocompleteElement();
document.body.appendChild(placeAutocomplete);
```

### JavaScript

```javascript
// Request needed libraries.
const { PlaceAutocompleteElement } =
    await google.maps.importLibrary('places');
// Create the input HTML element, and append it.
const placeAutocomplete = new PlaceAutocompleteElement();
document.body.appendChild(placeAutocomplete);
```

[See the complete code example](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#example-maps)

### Add an Autocomplete widget to a map

If your billing address is outside of the
[European Economic Area (EEA)](https://developers.google.com/maps/comms/eea/faq.md.txt), you may also use the
Autocomplete widget with a Google Map.

To add an Autocomplete widget to a map, first request the needed libraries, as shown here:

```javascript
// In your TS or JS, request the needed libraries.
const { PlaceAutocompleteElement } = await google.maps.importLibrary("places");
```

Then in your HTML, nest a new `gmp-place-autocomplete` element within a
`div`, and nest that `div` within a `gmp-map`, as shown in the
following example:

```html
<gmp-map center="40.749933,-73.98633" zoom="13" map-id="DEMO_MAP_ID">
    <div
        class="place-autocomplete-card"
        slot="control-inline-start-block-start">
        <gmp-place-autocomplete
            placeholder="Search for a place..."></gmp-place-autocomplete>
    </div>
</gmp-map>
```

To programmatically add an Autocomplete widget to a map, create a new
[`google.maps.places.PlaceAutocompleteElement`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElement)
instance, append the
[`PlaceAutocompleteElement`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElement)
to a `div`, and apply the `slot` attribute to the
`div`, as shown in the following example:

```javascript
// In your TS or JS, request the needed libraries.
const { PlaceAutocompleteElement } = await google.maps.importLibrary("places");

// Get the map element.
const mapElement = document.querySelector('gmp-map') as google.maps.MapElement;

// Create the PlaceAutocompleteElement instance.
const placeAutocomplete = new PlaceAutocompleteElement({});

// Create a div and append the PlaceAutocompleteElement to it.
const card = document.createElement("div");
card.appendChild(placeAutocomplete);

// Apply the slot attribute to the div.
// This positions the control in the top-left corner of the map.
card.setAttribute("slot", "control-inline-start-block-start");

// Append the div to the map element (check for null).
if (mapElement) {
    mapElement.appendChild(card);
}
```

[See the complete code example](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#example-maps)

### Add placeholder text

Use the
[`placeholder`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElement.placeholder)
property to add placeholder text. The following example shows setting the
placeholder text in HTML:

```html
<gmp-place-autocomplete
  placeholder="Search for a place..."
></gmp-place-autocomplete>
```

You can also set the placeholder text programmatically:

```javascript
placeAutocomplete.placeholder = 'Search for a place...';
```

### Constrain Autocomplete predictions

By default, Place Autocomplete presents all place types, biased for
predictions near the user's location, and fetches all available data fields
for the user's selected place. Set
[`PlaceAutocompleteElementOptions`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElementOptions)
to present more relevant predictions, by restricting or biasing results.

Restricting results causes the Autocomplete widget to ignore any results that are outside of the
restriction area. A common practice is to restrict results to the map bounds. Biasing results
makes the Autocomplete widget show results within the specified area, but some matches may be
outside of that area.

If you don't supply any bounds or a map viewport, the API will attempt to detect the user's
location from their IP address, and will bias the results to that location. Set a bounds whenever
possible. Otherwise, different users may receive different predictions. Also, to generally improve
predictions it is important to provide a sensible viewport such as one that you set by panning or
zooming on the map, or a developer-set viewport based on device location and radius. When a radius
is not available, 5 km is considered a sensible default for Place Autocomplete. Don't set a
viewport with zero radius (a single point), a viewport that is only a few meters across (less than
100 meters), or a viewport that spans the globe.

#### Restrict place search by country

To restrict place search to one or more specific countries, use the
[`includedRegionCodes`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElement.includedRegionCodes)
property to specify the country code(s) as shown in the following snippet
(these assume you have already created an instance named
`placeAutocomplete`):

```javascript
placeAutocomplete.includedRegionCodes = ['us', 'au'];;
```

#### Restrict place search to map bounds

To restrict place search to a map's bounds, use the
[`locationRestriction`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElement.locationRestriction)
property. The following snippet shows how to add a listener to update the bounds when they
change:

```javascript
// Use the bounds_changed event to restrict results to the current map bounds.
google.maps.event.addListener(innerMap, 'bounds_changed', async () => {
    placeAutocomplete.locationRestriction = innerMap.getBounds();
});
```

To remove the
[`locationRestriction`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElement.locationRestriction),
set it to `null`.

#### Bias place search results

Bias place search results to a circle area by using the
[`locationBias`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElement.locationBias)
property, as shown here:

```javascript
placeAutocomplete.locationBias = {radius: 100, center: {lat: 40.749933, lng: -73.98633}};
```

To remove the
[`locationBias`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElement.locationBias),
set it to `null`.

#### Restrict place search results to certain types

Restrict place search results to certain types of places by using the
[`includedPrimaryTypes`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElement.includedPrimaryTypes)
property, and specifying one or more types, as shown here:

```javascript
const autocomplete = new google.maps.places.PlaceAutocompleteElement({
  includedPrimaryTypes: ['establishment'],
});
```

For a complete list of supported types, see
[Place type tables A and B](https://developers.google.com/maps/documentation/places/web-service/place-types.md.txt).

## Get place details

To get place details for the selected place, add a
[`gmp-select`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElement.gmp-select)
listener to the
[`PlaceAutocompleteElement`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlaceAutocompleteElement),
as shown in the following example:

### TypeScript

```typescript
// Add the gmp-select listener, and display the results.
placeAutocomplete.addEventListener(
    'gmp-select',
    async ({
        placePrediction,
    }: google.maps.places.PlacePredictionSelectEvent) => {
        const place = placePrediction.toPlace();
        await place.fetchFields({
            fields: ['displayName', 'formattedAddress', 'location'],
        });
        selectedPlaceTitle.textContent = 'Selected Place:';
        selectedPlaceInfo.textContent = JSON.stringify(
            place.toJSON(),
            /* replacer */ null,
            /* space */ 2
        );
    }
);
```

### JavaScript

```javascript
// Add the gmp-select listener, and display the results.
placeAutocomplete.addEventListener(
    'gmp-select',
    async ({ placePrediction }) => {
        const place = placePrediction.toPlace();
        await place.fetchFields({
            fields: ['displayName', 'formattedAddress', 'location'],
        });
        selectedPlaceTitle.textContent = 'Selected Place:';
        selectedPlaceInfo.textContent = JSON.stringify(
            place.toJSON(),
            /* replacer */ null,
            /* space */ 2
        );
    }
);
```

[See the complete code example](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#example-maps)

In the preceding example, the event listener receives a
[`PlacePredictionSelectEvent`](https://developers.google.com/maps/documentation/javascript/reference/places-widget.md.txt#PlacePredictionSelectEvent)
and calls
[`placePrediction.toPlace()`](https://developers.google.com/maps/documentation/javascript/reference/autocomplete-data.md.txt#PlacePrediction.toPlace)
to get a
[Place class](https://developers.google.com/maps/documentation/javascript/place.md.txt)
([`Place`](https://developers.google.com/maps/documentation/javascript/reference/place.md.txt#Place)
reference) instance. Call
[`place.fetchFields()`](https://developers.google.com/maps/documentation/javascript/reference/place.md.txt#Place.fetchFields)
to get the Place Details
[data fields](https://developers.google.com/maps/documentation/javascript/place-class-data-fields.md.txt)
needed for your application.

The listener in the next example requests the
[`displayName`](https://developers.google.com/maps/documentation/javascript/reference/place.md.txt#Place.displayName),
[`formattedAddress`](https://developers.google.com/maps/documentation/javascript/reference/place.md.txt#Place.formattedAddress),
[`location`](https://developers.google.com/maps/documentation/javascript/reference/place.md.txt#Place.location),
and
[`viewport`](https://developers.google.com/maps/documentation/javascript/reference/place.md.txt#Place.viewport)
fields in
[`place.fetchFields()`](https://developers.google.com/maps/documentation/javascript/reference/place.md.txt#Place.fetchFields),
then uses
[`place.viewport`](https://developers.google.com/maps/documentation/javascript/reference/place.md.txt#Place.viewport)
with
[`fitBounds()`](https://developers.google.com/maps/documentation/javascript/reference/map.md.txt#Map.fitBounds)
to display the selected place on a map.

### TypeScript

```typescript
// Add the gmp-select listener, and display the results on the map.
placeAutocomplete.addEventListener(
    'gmp-select',
    async ({ placePrediction }) => {
        const place = placePrediction.toPlace();
        await place.fetchFields({
            fields: [
                'displayName',
                'formattedAddress',
                'location',
                'viewport',
            ],
        });

        // If the place has a geometry, then present it on a map.
        if (place.viewport) {
            innerMap.fitBounds(place.viewport);
        } else {
            innerMap.setCenter(place.location!);
            innerMap.setZoom(17);
        }

        const content = document.createElement('div');
        const nameText = document.createElement('span');
        nameText.textContent = place.displayName ?? 'No name';
        content.appendChild(nameText);
        content.appendChild(document.createElement('br'));
        const addressText = document.createElement('span');
        addressText.textContent = place.formattedAddress ?? 'No address';
        content.appendChild(addressText);

        updateInfoWindow(content, place.location);
        marker.position = place.location;
    }
);
```

### JavaScript

```javascript
// Add the gmp-select listener, and display the results on the map.
placeAutocomplete.addEventListener(
    'gmp-select',
    async ({ placePrediction }) => {
        const place = placePrediction.toPlace();
        await place.fetchFields({
            fields: [
                'displayName',
                'formattedAddress',
                'location',
                'viewport',
            ],
        });

        // If the place has a geometry, then present it on a map.
        if (place.viewport) {
            innerMap.fitBounds(place.viewport);
        } else {
            innerMap.setCenter(place.location);
            innerMap.setZoom(17);
        }

        const content = document.createElement('div');
        const nameText = document.createElement('span');
        nameText.textContent = place.displayName ?? 'No name';
        content.appendChild(nameText);
        content.appendChild(document.createElement('br'));
        const addressText = document.createElement('span');
        addressText.textContent = place.formattedAddress ?? 'No address';
        content.appendChild(addressText);

        updateInfoWindow(content, place.location);
        marker.position = place.location;
    }
);
```

[See the complete code example](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#example-maps)

## Example maps

This section contains the complete code for the example maps featured on this page.

### Autocomplete element

This example adds an Autocomplete widget to a web page, and displays the results for each
selected place.
<iframe src="https://maps-docs-team.web.app/samples/place-autocomplete-element/dist/" allow="fullscreen; fullscreen"></iframe>

### TypeScript

```typescript
async function init(): Promise<void> {
    // Request needed libraries.
    const { PlaceAutocompleteElement } =
        await google.maps.importLibrary('places');
    // Create the input HTML element, and append it.
    const placeAutocomplete = new PlaceAutocompleteElement();
    document.body.appendChild(placeAutocomplete);

    // Inject HTML UI.
    const selectedPlaceTitle = document.createElement('p');
    selectedPlaceTitle.textContent = '';
    document.body.appendChild(selectedPlaceTitle);

    const selectedPlaceInfo = document.createElement('pre');
    selectedPlaceInfo.textContent = '';
    document.body.appendChild(selectedPlaceInfo);

    // Add the gmp-select listener, and display the results.
    placeAutocomplete.addEventListener(
        'gmp-select',
        async ({
            placePrediction,
        }: google.maps.places.PlacePredictionSelectEvent) => {
            const place = placePrediction.toPlace();
            await place.fetchFields({
                fields: ['displayName', 'formattedAddress', 'location'],
            });
            selectedPlaceTitle.textContent = 'Selected Place:';
            selectedPlaceInfo.textContent = JSON.stringify(
                place.toJSON(),
                /* replacer */ null,
                /* space */ 2
            );
        }
    );
}

void init();
```

### JavaScript

```javascript
async function init() {
    // Request needed libraries.
    const { PlaceAutocompleteElement } =
        await google.maps.importLibrary('places');
    // Create the input HTML element, and append it.
    const placeAutocomplete = new PlaceAutocompleteElement();
    document.body.appendChild(placeAutocomplete);

    // Inject HTML UI.
    const selectedPlaceTitle = document.createElement('p');
    selectedPlaceTitle.textContent = '';
    document.body.appendChild(selectedPlaceTitle);

    const selectedPlaceInfo = document.createElement('pre');
    selectedPlaceInfo.textContent = '';
    document.body.appendChild(selectedPlaceInfo);

    // Add the gmp-select listener, and display the results.
    placeAutocomplete.addEventListener(
        'gmp-select',
        async ({ placePrediction }) => {
            const place = placePrediction.toPlace();
            await place.fetchFields({
                fields: ['displayName', 'formattedAddress', 'location'],
            });
            selectedPlaceTitle.textContent = 'Selected Place:';
            selectedPlaceInfo.textContent = JSON.stringify(
                place.toJSON(),
                /* replacer */ null,
                /* space */ 2
            );
        }
    );
}

void init();
```

### CSS

```css
/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
    height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

p {
    font-family: Roboto, sans-serif;
    font-weight: bold;
}
```

### HTML

```html
<html>
    <head>
        <title>Place Autocomplete element</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <script>
            // prettier-ignore
            (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
                key: "GOOGLE_MAPS_API_KEY"
            });
        </script>
    </head>
    <body>
        <p style="font-family: roboto, sans-serif">Search for a place here:</p>
    </body>
</html>
```

### Try Sample

[JSFiddle.net](https://jsfiddle.net/gh/get/library/pure/googlemaps-samples/js-api-samples/tree/main/dist/samples/place-autocomplete-element/jsfiddle)

### Autocomplete map

This example shows you how to add an Autocomplete widget to a Google map.
<iframe src="https://maps-docs-team.web.app/samples/place-autocomplete-map/dist/" allow="fullscreen; fullscreen"></iframe>

### TypeScript

```typescript
const mapElement = document.querySelector('gmp-map')!;
const placeAutocomplete = document.querySelector('gmp-place-autocomplete')!;
let innerMap: google.maps.Map;
let marker: google.maps.marker.AdvancedMarkerElement;
let infoWindow: google.maps.InfoWindow;
async function init(): Promise<void> {
    // Request needed libraries.
    const [{ AdvancedMarkerElement }, { InfoWindow }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('places'),
    ]);

    // Get the inner map.
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });

    // Use the bounds_changed event to restrict results to the current map bounds.
    innerMap.addListener('bounds_changed', () => {
        placeAutocomplete.locationRestriction = innerMap.getBounds()!;
    });

    // Create the marker and infoWindow.
    marker = new AdvancedMarkerElement({
        map: innerMap,
    });

    infoWindow = new InfoWindow();

    // Add the gmp-select listener, and display the results on the map.
    placeAutocomplete.addEventListener(
        'gmp-select',
        async ({ placePrediction }) => {
            const place = placePrediction.toPlace();
            await place.fetchFields({
                fields: [
                    'displayName',
                    'formattedAddress',
                    'location',
                    'viewport',
                ],
            });

            // If the place has a geometry, then present it on a map.
            if (place.viewport) {
                innerMap.fitBounds(place.viewport);
            } else {
                innerMap.setCenter(place.location!);
                innerMap.setZoom(17);
            }

            const content = document.createElement('div');
            const nameText = document.createElement('span');
            nameText.textContent = place.displayName ?? 'No name';
            content.appendChild(nameText);
            content.appendChild(document.createElement('br'));
            const addressText = document.createElement('span');
            addressText.textContent = place.formattedAddress ?? 'No address';
            content.appendChild(addressText);

            updateInfoWindow(content, place.location);
            marker.position = place.location;
        }
    );
}

// Helper function to create an info window.
function updateInfoWindow(
    content: string | Element | Text | null | undefined,
    center: google.maps.LatLng | google.maps.LatLngLiteral | null | undefined
) {
    infoWindow.setContent(content);
    infoWindow.setPosition(center);
    infoWindow.open({
        map: innerMap,
        anchor: marker,
        shouldFocus: false,
    });
}

void init();
```

### JavaScript

```javascript
const mapElement = document.querySelector('gmp-map');
const placeAutocomplete = document.querySelector('gmp-place-autocomplete');
let innerMap;
let marker;
let infoWindow;
async function init() {
    // Request needed libraries.
    const [{ AdvancedMarkerElement }, { InfoWindow }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('places'),
    ]);

    // Get the inner map.
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });

    // Use the bounds_changed event to restrict results to the current map bounds.
    innerMap.addListener('bounds_changed', () => {
        placeAutocomplete.locationRestriction = innerMap.getBounds();
    });

    // Create the marker and infoWindow.
    marker = new AdvancedMarkerElement({
        map: innerMap,
    });

    infoWindow = new InfoWindow();

    // Add the gmp-select listener, and display the results on the map.
    placeAutocomplete.addEventListener(
        'gmp-select',
        async ({ placePrediction }) => {
            const place = placePrediction.toPlace();
            await place.fetchFields({
                fields: [
                    'displayName',
                    'formattedAddress',
                    'location',
                    'viewport',
                ],
            });

            // If the place has a geometry, then present it on a map.
            if (place.viewport) {
                innerMap.fitBounds(place.viewport);
            } else {
                innerMap.setCenter(place.location);
                innerMap.setZoom(17);
            }

            const content = document.createElement('div');
            const nameText = document.createElement('span');
            nameText.textContent = place.displayName ?? 'No name';
            content.appendChild(nameText);
            content.appendChild(document.createElement('br'));
            const addressText = document.createElement('span');
            addressText.textContent = place.formattedAddress ?? 'No address';
            content.appendChild(addressText);

            updateInfoWindow(content, place.location);
            marker.position = place.location;
        }
    );
}

// Helper function to create an info window.
function updateInfoWindow(content, center) {
    infoWindow.setContent(content);
    infoWindow.setPosition(center);
    infoWindow.open({
        map: innerMap,
        anchor: marker,
        shouldFocus: false,
    });
}

void init();
```

### CSS

```css
/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
gmp-map {
    height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

.place-autocomplete-card {
    background-color: #fff;
    border-radius: 5px;
    box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
    margin: 10px;
    padding: 5px;
    font-family: Roboto, sans-serif;
    font-size: small;
}

gmp-place-autocomplete {
    width: 300px;
}

#infowindow-content .title {
    font-weight: bold;
}

#map #infowindow-content {
    display: inline;
}
```

### HTML

```html
<html>
    <head>
        <title>Place Autocomplete map</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <script>
            // prettier-ignore
            (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
                key: "GOOGLE_MAPS_API_KEY"
            });
        </script>
    </head>
    <body>
        <gmp-map center="40.749933,-73.98633" zoom="13" map-id="DEMO_MAP_ID">
            <div
                class="place-autocomplete-card"
                slot="control-inline-start-block-start">
                <gmp-place-autocomplete
                    placeholder="Search for a place..."></gmp-place-autocomplete>
            </div>
        </gmp-map>
    </body>
</html>
```

### Try Sample

[JSFiddle.net](https://jsfiddle.net/gh/get/library/pure/googlemaps-samples/js-api-samples/tree/main/dist/samples/place-autocomplete-map/jsfiddle)

## Autocomplete (New) optimization

This section describes best practices to help you make the most of the
Autocomplete (New) service.

Here are some general guidelines:

- The quickest way to develop a working user interface is to use the Maps JavaScript API [Autocomplete (New) widget](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt), Places SDK for Android [Autocomplete (New) widget](https://developers.google.com/maps/documentation/places/android-sdk/place-autocomplete.md.txt#autocomplete-widget), or Places SDK for iOS [Autocomplete (New) widget](https://developers.google.com/maps/documentation/places/ios-sdk/place-autocomplete.md.txt#autocomplete-widget).
- Understand essential Autocomplete (New) [data fields](https://developers.google.com/maps/documentation/javascript/place-class-data-fields.md.txt) from the start.
- Location biasing and location restriction fields are optional but can have a significant impact on autocomplete performance.
- Use error handling to make sure your app degrades gracefully if the API returns an error.
- Make sure your app handles when there is no selection and offers users a way to continue.

### Cost optimization best practices

### Basic cost optimization

[Video](https://www.youtube.com/watch?v=VOP8cvCLGac)

To optimize the cost of using the Autocomplete (New)
service, use field masks in Place Details (New) and Autocomplete (New) widgets to return only the

Autocomplete (New) [data fields](https://developers.google.com/maps/documentation/javascript/place-class-data-fields.md.txt)

you need.

### Advanced cost optimization

Consider programmatic implementation of Autocomplete (New) to access

[SKU: Autocomplete Request pricing](https://developers.google.com/maps/billing-and-pricing/sku-details/places.md.txt#places_autocomplete-request-new-ess-sku)

and request [Geocoding API results](https://developers.google.com/maps/documentation/geocoding/overview#results) about the selected place instead of Place Details (New). Per-request pricing paired with Geocoding API is more cost-effective than per-session (session-based) pricing if both of the following conditions are met:

- If you only need the latitude and longitude or address of the user's selected place, the Geocoding API delivers this information for less than a Place Details (New) call.
- If users select an autocomplete prediction within an average of four Autocomplete (New) predictions requests or fewer, per-request pricing can be more cost-effective than per-session pricing.

To choose the Autocomplete (New) implementation that costs the least for your application, find the row in the following table that matches what your application needs.

| What your application needs | Average Autocomplete (New) requests before a user selects a prediction | Recommended implementation |
|---|---|---|
| Place details other than the address and location, such as the place name, business status, or opening hours | Any number | [Session-based Autocomplete (New) with Place Details (New)](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#select-place-details) |
| Only the address and latitude/longitude of the selected prediction | Four or fewer | [Per-request Autocomplete (New) with the Geocoding API](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#select-location-performant) |
| Only the address and latitude/longitude of the selected prediction | More than four | [Session-based Autocomplete (New) for address-only applications](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#select-location-nonperformant) |


Geocoding API could be a more cost-effective option than Place Details (New) for your application, depending on the performance of your Autocomplete (New) usage. Every application's Autocomplete (New) efficiency varies depending on what users are entering, where the application is being used, and whether [performance optimization best practices](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#perf-best-practices) have been implemented.


To find the average number of requests for the table, analyze how many characters a user types on average before selecting a Autocomplete (New) prediction in your application.

### Session-based Autocomplete (New) with Place Details (New)


**Use session-based Autocomplete (New) with Place Details (New).**   


Since your application requires Place Details (New), such as the place name, business status,
or opening hours, your implementation of Autocomplete (New) should use a session token
(programmatically or built into the
[JavaScript](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt),
[Android](https://developers.google.com/maps/documentation/places/android-sdk/place-autocomplete.md.txt#autocomplete-widget),
or [iOS](https://developers.google.com/maps/documentation/places/ios-sdk/place-autocomplete.md.txt#autocomplete-widget)
widgets)
[per session](https://developers.google.com/maps/documentation/javascript/session-pricing.md.txt) plus applicable Places SKUs,
depending on which place data fields you request.^[1](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#fn1)^


**Widget implementation**   

Session management is automatically built into the

[JavaScript](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt),
[Android](https://developers.google.com/maps/documentation/places/android-sdk/place-autocomplete.md.txt#autocomplete-widget),
or [iOS](https://developers.google.com/maps/documentation/places/ios-sdk/place-autocomplete.md.txt#autocomplete-widget)

widgets. This includes both the Autocomplete (New) requests and the Place Details (New) request
on the selected prediction. Be sure to specify the `fields` parameter in order to
ensure you are only requesting the

Autocomplete (New) [data fields](https://developers.google.com/maps/documentation/javascript/place-class-data-fields.md.txt)

you need.


**Programmatic implementation**   

Use a

[session token](https://developers.google.com/maps/documentation/javascript/session-pricing.md.txt)

with your Autocomplete (New) requests. When requesting Place Details (New) about the selected prediction, include the following parameters:

1. The place ID from [the Autocomplete (New) response](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#programmatic-response)
2. The session token used in the Autocomplete (New) request
3. The `fields` parameter specifying the Autocomplete (New) [data fields](https://developers.google.com/maps/documentation/javascript/place-class-data-fields.md.txt) you need

### Per-request Autocomplete (New) with the Geocoding API


**Implement Autocomplete (New) programmatically without session tokens and call Geocoding API on the selected place prediction.**   

Geocoding API delivers addresses and latitude/longitude coordinates.
Making four

[Autocomplete Requests](https://developers.google.com/maps/billing-and-pricing/sku-details/places.md.txt#places_autocomplete-request-new-ess-sku)

requests plus a [Geocoding API](https://developers.google.com/maps/billing-and-pricing/sku-details/places.md.txt#geocoding-ess-sku)
call about the selected place prediction is less than the per-session Autocomplete (New)
cost per session.^[1](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#fn1)^


Consider employing [performance best practices](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#perf-best-practices) to help your users get the prediction they're looking for in even fewer characters.

### Session-based Autocomplete (New) for address-only applications


**Use session-based Autocomplete (New) with Place Details (New).**   

Since the average number of requests you expect to make before a user selects a
Autocomplete (New) prediction exceeds the cost of per-session pricing, your implementation
of Autocomplete (New) should use a session token for both the Autocomplete (New) requests
and the associated Place Details (New) request

[per session](https://developers.google.com/maps/documentation/javascript/session-pricing.md.txt).

^[1](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#fn1)^


**Widget implementation**   

Session management is automatically built into the

[JavaScript](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt),
[Android](https://developers.google.com/maps/documentation/places/android-sdk/place-autocomplete.md.txt#autocomplete-widget),
or [iOS](https://developers.google.com/maps/documentation/places/ios-sdk/place-autocomplete.md.txt#autocomplete-widget)

widgets. This includes both the Autocomplete (New) requests and the Place Details (New)
request on the selected prediction. Be sure to specify the `fields` parameter
in order to ensure you are only requesting the fields you need.


**Programmatic implementation**   

Use a

[session token](https://developers.google.com/maps/documentation/javascript/session-pricing.md.txt)

with your Autocomplete (New) requests.
When requesting Place Details (New) about the selected prediction,
include the following parameters:

1. The place ID from [the Autocomplete (New) response](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#programmatic-response)
2. The session token used in the Autocomplete (New) request
3. The `fields` parameter specifying fields such as address and geometry


**Consider delaying Autocomplete (New) requests**   

You can employ strategies such as delaying a Autocomplete (New) request until the user has typed in the first three or four characters so that your application makes fewer requests. For example, making Autocomplete (New) requests for each character *after* the user has typed the third character means that if the user types seven characters then selects a prediction for which you make one Geocoding API request, the total cost would be for 4 Autocomplete (New) Per Request + Geocoding.^[1](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#fn1)^


If delaying requests can get your average programmatic request below four, you can follow the guidance for [performant Autocomplete (New) with Geocoding API](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#select-location-performant) implementation. Note that delaying requests can be perceived as latency by the user who might be expecting to see predictions with every new keystroke.


Consider employing [performance best practices](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#perf-best-practices) to help your users get the prediction they're looking for in fewer characters.

*** ** * ** ***

1. For costs, see [Google Maps Platform pricing lists](https://developers.google.com/maps/billing-and-pricing/pricing.md.txt).

### Performance best practices

[Video](https://www.youtube.com/watch?v=bv1p4s_d8OM)

The following guidelines describe ways to optimize Autocomplete (New) performance:

- Add country restrictions, [location biasing](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#location_biasing), and (for programmatic implementations) language preference to your Autocomplete (New) implementation. Language preference is not needed with widgets since they pick language preferences from the user's browser or mobile device.
- If Autocomplete (New) is accompanied by a map, you can bias location by map viewport.
- In situations when a user does not choose one of the Autocomplete (New) predictions, generally because none of those predictions are the result-address wanted, you can reuse the original user input to attempt to get more relevant results:
  - If you expect the user to enter only address information, reuse the original user input in a call to the [Geocoding API](https://developers.google.com/maps/documentation/geocoding/overview).
  - If you expect the user to enter queries for a specific place by name or address, use a Place Details (New) request. If results are only expected in a specific region, use [location biasing](https://developers.google.com/maps/documentation/javascript/place-autocomplete-new.md.txt#location_biasing).

  Other scenarios when it's best to fall back to the Geocoding API include:
  <!-- -->

  - Users inputting subpremise addresses, such as addresses for specific units or apartments within a building. For example, the Czech address "Stroupežnického 3191/17, Praha" yields a partial prediction in Autocomplete (New).
  - Users inputting addresses with road-segment prefixes like "23-30 29th St, Queens" in New York City or "47-380 Kamehameha Hwy, Kaneohe" on the island of Kauai in Hawai'i.

### Location biasing

Bias results to a specified area by passing a `location` parameter and a `radius`
parameter. This instructs Autocomplete (New) to *prefer* showing results
within the defined area. Results outside of the defined area may still be
displayed. You can use the `includedRegionCodes` parameter to filter results
to show only those places within a specified country.

> [!WARNING]
> **Warning:** If `radius` is not provided, the `location` parameter is ignored.

> [!TIP]
> Establishment results generally don't rank highly enough to show in results when the search area is large. If you want establishments to appear in mixed establishment/geocode results, you can specify a smaller radius. Alternatively, use `types=establishment` to restrict results to establishments only.

### Location restricting

Restrict results to a specified area by passing a `locationRestriction` parameter.

You may also restrict results to the region defined by `location`
and a `radius` parameter, by adding the

`locationRestriction`

parameter. This instructs Autocomplete (New) to return *only*
results within that region.

> [!NOTE]
> **Note:** Location restrictions are only applied to entire routes. Synthetic results located outside the location restriction may be returned based on a route that overlaps with the location restriction.