SkillAgentSearch skills...

Use Places Autocomplete

😎 πŸ“ React hook for Google Maps Places Autocomplete.

Install / Use

npx skills add wellyshen/use-places-autocomplete

Installs into whichever agent you are using.

README

πŸ‘€ We're actively seeking dedicated maintainers for the repo β€” if you're interested, please contact me directly.

<em><b>USE-PLACES-AUTOCOMPLETE</b></em>

This is a React hook for Google Maps Places Autocomplete, which helps you build a UI component with the feature of place autocomplete easily! By leveraging the power of Google Maps Places API, you can provide a great UX (user experience) for user interacts with your search bar or form, etc. Hope you guys πŸ‘πŸ» it.

❀️ it? ⭐️ it on GitHub or Tweet about it.

build status coverage status npm version npm downloads npm downloads gzip size All Contributors PRs welcome Twitter URL

Live Demo

demo

⚑️ Try yourself: https://use-places-autocomplete.netlify.app

Features

  • 🧠 Provides intelligent places suggestions powered by Google Maps Places API.
  • 🎣 Builds your own customized autocomplete UI by React hook.
  • πŸ”§ Utility functions to do geocoding and get geographic coordinates using Google Maps Geocoding API.
  • πŸ€‘ Built-in cache mechanism for you to save the cost of Google APIs.
  • πŸ’° Built-in debounce mechanism for you to lower the cost of Google APIs.
  • πŸš€ Supports asynchronous Google script loading.
  • πŸ“œ Supports TypeScript type definition.
  • ⌨️ Builds a UX-rich component (e.g. WAI-ARIA compliant and keyword support) via comprehensive demo code.
  • πŸ¦” Tiny size (~ 1.7KB gzipped). No external dependencies, aside from the react.

Requirement

To use use-places-autocomplete, you must use react@16.8.0 or greater which includes hooks.

Installation

This package is distributed via npm.

$ yarn add use-places-autocomplete
# or
$ npm install --save use-places-autocomplete

When working with TypeScript you need to install the @types/google.maps as a devDependencies.

$ yarn add --dev @types/google.maps
# or
$ npm install --save-dev @types/google.maps

Getting Started

usePlacesAutocomplete is based on the Places Autocomplete (or more specific docs) of Google Maps Place API. If you are unfamiliar with these APIs, we recommend you review them before we start.

Setup APIs

To use this hook, there're two things we need to do:

  1. Enable Google Maps Places API.
  2. Get an API key.

Load the library

Use the script tag to load the library in your project and pass the value of the callback parameter to the callbackName option.

<script
  defer
  src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=YOUR_CALLBACK_NAME"
></script>

⚠️ If you got a global function not found error. Make sure usePlaceAutocomplete is declared before the script was loaded. You can use the async or defer attribute of the <script> element to achieve that.

Create the component

Now we can start to build our component. Check the API out to learn more.

import usePlacesAutocomplete, {
  getGeocode,
  getLatLng,
} from "use-places-autocomplete";
import useOnclickOutside from "react-cool-onclickoutside";

const PlacesAutocomplete = () => {
  const {
    ready,
    value,
    suggestions: { status, data },
    setValue,
    clearSuggestions,
  } = usePlacesAutocomplete({
    callbackName: "YOUR_CALLBACK_NAME",
    requestOptions: {
      /* Define search scope here */
    },
    debounce: 300,
  });
  const ref = useOnclickOutside(() => {
    // When the user clicks outside of the component, we can dismiss
    // the searched suggestions by calling this method
    clearSuggestions();
  });

  const handleInput = (e) => {
    // Update the keyword of the input element
    setValue(e.target.value);
  };

  const handleSelect =
    ({ description }) =>
    () => {
      // When the user selects a place, we can replace the keyword without request data from API
      // by setting the second parameter to "false"
      setValue(description, false);
      clearSuggestions();

      // Get latitude and longitude via utility functions
      getGeocode({ address: description }).then((results) => {
        const { lat, lng } = getLatLng(results[0]);
        console.log("πŸ“ Coordinates: ", { lat, lng });
      });
    };

  const renderSuggestions = () =>
    data.map((suggestion) => {
      const {
        place_id,
        structured_formatting: { main_text, secondary_text },
      } = suggestion;

      return (
        <li key={place_id} onClick={handleSelect(suggestion)}>
          <strong>{main_text}</strong> <small>{secondary_text}</small>
        </li>
      );
    });

  return (
    <div ref={ref}>
      <input
        value={value}
        onChange={handleInput}
        disabled={!ready}
        placeholder="Where are you going?"
      />
      {/* We can use the "status" to decide whether we should display the dropdown or not */}
      {status === "OK" && <ul>{renderSuggestions()}</ul>}
    </div>
  );
};

πŸ’‘ react-cool-onclickoutside is my other hook library, which can help you handle the interaction of user clicks outside of the component(s).

Easy right? This is the magic of usePlacesAutocomplete ✨. I just showed you how it works via a minimal example. However, you can build a UX rich autocomplete component, like WAI-ARIA compliant and keyword interaction like my demo, by checking the code or integrating this hook with the combobox of Reach UI to achieve that.

Edit usePlacesAutocomplete x Reach UI

import usePlacesAutocomplete from "use-places-autocomplete";
import {
  Combobox,
  ComboboxInput,
  ComboboxPopover,
  ComboboxList,
  ComboboxOption,
} from "@reach/combobox";

import "@reach/combobox/styles.css";

const PlacesAutocomplete = () => {
  const {
    ready,
    value,
    suggestions: { status, data },
    setValue,
  } = usePlacesAutocomplete({ callbackName: "YOUR_CALLBACK_NAME" });

  const handleInput = (e) => {
    setValue(e.target.value);
  };

  const handleSelect = (val) => {
    setValue(val, false);
  };

  return (
    <Combobox onSelect={handleSelect} aria-labelledby="demo">
      <ComboboxInput value={value} onChange={handleInput} disabled={!ready} />
      <ComboboxPopover>
        <ComboboxList>
          {status === "OK" &&
            data.map(({ place_id, description }) => (
              <ComboboxOption key={place_id} value={description} />
            ))}
        </ComboboxList>
      </ComboboxPopover>
    </Combobox>
  );
};

Lazily Initializing The Hook

When loading the Google Maps Places API via a 3rd-party library, you

Related Skills

View on GitHub
GitHub Stars1.3k
CategoryDevelopment
Updated1mo ago
Forks68

Languages

TypeScript

Security Score

100/100

Audited on Jun 29, 2026

No findings