Skip to content

A flexible and customizable vanilla JavaScript library leveraging the Google Maps Places (New) Autocomplete API. This library provides a user-friendly way to search for and retrieve detailed address information in any web application.

License

MIT, MIT licenses found

Licenses found

MIT
LICENCE
MIT
LICENSE
Notifications You must be signed in to change notification settings

alexpechkarev/places-autocomplete-js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Places (New) Autocomplete - JavaScript Library

npm version License: MIT

A flexible and customisable vanilla JavaScript library for frontend web applications, leveraging the Google Maps Places (New) Autocomplete API. This library provides a user-friendly way to search for and retrieve detailed address and location information in any web application.

It handles API loading, session tokens for cost-effective usage, fetching suggestions with debouncing, keyboard navigation, highlighting matched text, and requesting place details, allowing you to focus on integrating the results into your application.

Live Demo

Explore interactive examples of the Google Places Autocomplete JS library:

A quick, editable sandbox to experiment with the core functionality:

Try it on CodePen

See a more comprehensive live demo of the library in action: pacservice.pages.dev

A video demonstrating the Places Autocomplete JavaScript component in action, showing address suggestions and selection.

Features

  • Seamless Google Places Integration: Directly connects with the modern Google Places (New) Autocomplete API for accurate and up-to-date address suggestions.
  • Cost-Effective API Usage: Automatically handles session tokens to optimise your Google Maps API costs per Google's guidelines.
  • Optimised User Experience: Implements Debounced Input to limit API calls while the user is typing, ensuring a smooth and responsive search experience.
  • Enhanced Readability: Provides Suggestion Highlighting to automatically bold the portion of text matching the user's input, making suggestions easier to scan.
  • Flexible Styling: Offers Customisable Styling allowing you to easily override default styles or apply your own using CSS classes. Built with sensible defaults (Tailwind CSS utility classes by default but can be entirely replaced).
  • Robust Event Handling: Provides onResponse and onError callbacks for comprehensive control over successful place selections and error scenarios.
  • Highly Configurable: Allows you to control API parameters (requestParams) and component behavior/appearance (options) to fit your specific application needs.
  • Efficient API Loading: Dynamically loads the Google Maps API script on demand, reducing initial page load times.

Benefits

  • Accelerate Development: Quickly integrate powerful address autocomplete functionality into your web application with minimal setup.
  • Improve User Experience: Provide a fast, intuitive, and accurate address entry experience for your users.
  • Reduce API Costs: Leverage automatic session token management to optimise your Google Maps API billing.
  • Maintain Brand Consistency: Easily customise the look and feel of the autocomplete component to match your application's design system.
  • Future-Proof: Built on the latest Google Places (New) Autocomplete API, ensuring compatibility and access to new features.

Requirements

  • Google Maps API Key with the Places API (New) enabled. Refer to Use API Keys for detailed instructions.

Installation & Usage

This library can be used in two primary ways: by installing it as an npm package for use with a bundler (like Vite or Webpack), or by linking to it directly from a CDN in a static HTML file.

1. With a Bundler (Recommended)

This is the recommended approach for modern web applications.

Step 1: Install the package

npm install places-autocomplete-js
# or
yarn add places-autocomplete-js

Step 2: Import and initialise the component

In your main JavaScript or TypeScript file, import both the library and its stylesheet.

import { PlacesAutocomplete } from 'places-autocomplete-js';
import 'places-autocomplete-js/dist/places-autocomplete.css'; // Import the default stylesheet

document.addEventListener('DOMContentLoaded', () => {
  try {
    const autocomplete = new PlacesAutocomplete({
      containerId: 'autocomplete-container',
      googleMapsApiKey: 'YOUR_GOOGLE_MAPS_API_KEY', // Replace with your key
      onResponse: (placeDetails) => {
        console.log('Place Selected:', placeDetails);
        // Your code to handle the selected place...
      },
      onError: (error) => {
        console.error('Autocomplete Error:', error.message || error);
      }
    });
  } catch (error) {
    console.error("Failed to initialise PlacesAutocomplete:", error.message);
  }
});

Then, add the container element to your HTML:

<div id="autocomplete-container"></div>

2. With a CDN Link (for Static HTML)

For quick prototyping or use in projects without a build step, you can use a CDN like jsDelivr.

Step 1: Add the stylesheet and script to your HTML

Add the following lines to your HTML file. The stylesheet goes in the <head> and the script goes at the end of the <body>.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Places Autocomplete Demo</title>
  
  <!-- 1. Link to the stylesheet -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/places-autocomplete-js@latest/dist/places-autocomplete.css">
  
</head>
<body>

  <!-- 2. Add the container for the component -->
  <div id="autocomplete-container"></div>

  <!-- 3. Link to the library's script -->
  <script type="module">
    // 4. Import the class from the script
    import { PlacesAutocomplete } from 'https://cdn.jsdelivr.net/npm/places-autocomplete-js@latest/dist/places-autocomplete.js';

    document.addEventListener('DOMContentLoaded', () => {
      try {
        const autocomplete = new PlacesAutocomplete({
          containerId: 'autocomplete-container',
          googleMapsApiKey: 'YOUR_GOOGLE_MAPS_API_KEY', // Replace with your key
          onResponse: (placeDetails) => {
            console.log('Place Selected:', placeDetails);
          }
        });
      } catch (error) {
        console.error("Failed to initialise PlacesAutocomplete:", error.message);
      }
    });
  </script>

</body>
</html>

Note for Production: For stability, it's recommended to pin the CDN links to a specific version instead of using @latest. For example: .../[email protected]/...

Configuration

The PlacesAutocomplete class is initialised with a configuration object.

Parameter Type Required Description
containerId string Yes The ID of the HTML element where the autocomplete widget will be rendered.
googleMapsApiKey string Yes Your Google Maps API Key with the Places API (New) enabled.
googleMapsApiVersion string No The version of the Google Maps API to load (e.g., "weekly", "quarterly", "beta"). Defaults to "weekly".
onResponse function No Callback function triggered with selected place details. Receives a Place object (see Google's docs). Default logs to console.
onError function No Callback function triggered when an error occurs. Receives an Error object or string. Default logs to console.
options object No Object to customise UI behavior and appearance. See "UI & Behavior Options" below.
requestParams object No Object to customise the parameters sent to the Google Places Autocomplete API. See "API Request Parameters" below.
fetchFields array No Array of Place Data Fields to request when a place is selected. Affects API cost. Default ['formattedAddress', 'addressComponents']

UI & Behavior Options (options)

Passed within the main configuration object under the options key.

Option Type Default Description
placeholder string "Start typing your address ..." Placeholder text for the input field.
debounce number 100 Delay in milliseconds before triggering an API request after user stops typing. Set to 0 to disable.
distance boolean true Whether to attempt to show distance in suggestions (requires origin in requestParams).
distance_units 'km' | 'miles' 'km' Units to display distance in if distance is true.
label string "" Optional label text displayed above the input field.
autofocus boolean false If true, automatically focuses the input field on initialisation.
autocomplete string 'off' Standard HTML autocomplete attribute for the input field.
classes object (See default classes below) Object to override default CSS classes for styling. See "Styling" section.
clear_input boolean true If true (default), clears the input field after a suggestion is selected. If false, the input field retains the formattedAddress of the selected place.

Styling

The component is built with flexibility in mind and can be styled in a couple of ways. The default appearance is based on Tailwind CSS, but you are not required to use Tailwind in your project.

Using the Pre-built CSS File

A standalone CSS file is included in the package (dist/places-autocomplete-js.css). This file contains all the necessary styles for the component to look and work correctly out-of-the-box.

CSS Classes (options.classes)

You can customise the appearance of the component by providing your own CSS classes via the options.classes object. The library uses a default set of classes (many are Tailwind CSS utility classes but can be entirely replaced).

Provide an object where keys are the component parts and values are the class strings you want to apply.

Default Class Keys & Structure:

  • section: The main container section.
  • container: The div containing the input and suggestions list.
  • label: The label element (if options.label is provided).
  • input: The main text input element.
  • icon_container: Container for the optional icon.
  • icon: SVG string for the icon.
  • ul: The <ul> element for the suggestions list.
  • li: Each <li> suggestion item.
  • li_current: Class added to the currently highlighted/selected <li> (keyboard/mouse).
  • li_a: The inner <a> or <button> element within each <li>.
  • li_a_current: Class added to the inner element when its <li> is current.
  • li_div_container: Container div within the <a>/<button>.
  • li_div_one: First inner div (usually contains the main text).
  • li_div_one_p: The <p> tag containing the main suggestion text.
  • li_div_two: Second inner div (usually contains the distance).
  • li_div_two_p: The <p> tag containing the distance text.
  • kbd_container: Container for the keyboard hint keys (Esc, Up, Down).
  • kbd_escape: The <kbd> tag for the 'Esc' hint.
  • kbd_up: The <kbd> tag for the 'Up Arrow' hint.
  • kbd_down: The <kbd> tag for the 'Down Arrow' hint.
  • highlight: The class applied to the <span> wrapping the matched text within suggestions. Defaults to 'font-bold'.

Example: Overriding Classes

const autocomplete = new PlacesAutocomplete({
  // ... other config
  options: {
    classes: {
      input: "my-custom-input form-control", // Replace default input style
      ul: "my-custom-dropdown-styles", // Custom dropdown style
      li_current: "my-active-suggestion", // Custom highlight for selected item
      highlight: "my-search-highlight", // Custom style for matched text
    },
  },
});

Then, style these classes in your CSS:

.my-custom-input {
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
}
.my-search-highlight {
  background-color: yellow;
  color: black;
}
/* etc. */

API Request Parameters (requestParams)

Passed within the main configuration object under the requestParams key. These parameters are sent to the Google Places Autocomplete API. Refer to the AutocompleteRequest documentation for all available options.

Common requestParams:

  • input: (string) Automatically handled by the library based on user typing.
  • language: (string) The language code, indicating in which language the results should be returned, if possible.
  • region: (string) The region code, specified as a ccTLD ("top-level domain") two-character value.
  • includedRegionCodes: (string[]) An array of up to 5 CLDR region codes to limit results to.
  • locationBias: (google.maps.places.LocationBias)
  • locationRestriction: (google.maps.places.LocationRestriction)
  • origin: (google.maps.LatLngLiteral) The origin point from which to calculate straight-line distances to predictions (if options.distance is true).
  • sessionToken: Automatically managed by this library.

Example requestParams:

const autocomplete = new PlacesAutocomplete({
  // ... other config
  requestParams: {
    language: "fr",
    region: "ca",
    includedRegionCodes: ["ca"],
    origin: { lat: 45.5019, lng: -73.5674 }, // Montreal
  },
});

Working with Fetch Fields (fetchFields)

The fetchFields option allows you to specify which fields of place data you want to retrieve when a user selects a suggestion. This can help reduce API costs by only fetching the necessary information. See the Place Class Data Fields for all available fields. By default, the library fetches ['formattedAddress', 'addressComponents'], but you can customise this based on your needs.

Example fetchFields:

const autocomplete = new PlacesAutocomplete({
  // ... other config
  fetchFields: ["formattedAddress", "addressComponents", "displayName"], // Fetch additional fields as needed
});

// Or
autocomplete.setFetchFields({
  fetchFields: ["formattedAddress", "addressComponents", "displayName"], // Update fetch fields dynamically
});

Retain Input Value After Selection

To keep the selected address visible in the input field after a suggestion is chosen. Set the options.clear_input = false.

const autocomplete = new PlacesAutocomplete({
  // ... other config
  options: {
    clear_input: false, // Retain the input value after selection
  },
});

Public Methods

Instances of PlacesAutocomplete have the following public methods:

  • clear(): Clears the input field and any visible suggestions, and refreshes the session token.

    autocomplete.clear();
  • destroy(): Removes event listeners and cleans up DOM elements created by the widget. Useful when the component is no longer needed (e.g., in SPAs when a view is unmounted).

    autocomplete.destroy();
  • setFetchFields(fields): Dynamically updates the array of Place Data Fields. The provided fields array will be combined with the library's default fields (formattedAddress, addressComponents), ensuring uniqueness, to form the new set of fields to request. Refer to the "Fetch Fields (fetchFields)" section and Place Class Data Fields for available fields.

    • fields (Array): An array of field names to fetch. These will be merged with the default fields (formattedAddress, addressComponents) and any existing fetch fields, ensuring uniqueness.
    // Example: Update to fetch displayName and geometry in addition to defaults
    autocomplete.setFetchFields(["displayName", "types"]);
    
    // Example: Set a specific list of fields, overriding previous settings (while still including defaults)
    autocomplete.setFetchFields(["regularOpeningHours", "websiteURI"]);
  • getFetchFields(): Retrieves the current array of Place Data Fields that will be requested when a place is selected.

    const currentFetchFields = autocomplete.getFetchFields();
    console.log("Current Fetch Fields:", currentFetchFields);
    // Expected output might be: ['formattedAddress', 'addressComponents', 'regularOpeningHours', 'websiteURI']
    // (depending on what was set via constructor or setFetchFields)
  • setRequestParams(params): Dynamically updates the parameters sent to the Google Places Autocomplete API. This allows you to change search criteria like language, region, or location bias after initialisation.

    • params (object): An object containing the API request parameters to update. These will be merged with existing request parameters. Refer to the "API Request Parameters (requestParams)" section for available options.
    // Example: Change the search region and language
    autocomplete.setRequestParams({
      region: "fr",
      language: "fr",
      includedRegionCodes: ["fr"],
    });
    
    // Example: Set an origin for distance calculations
    autocomplete.setRequestParams({
      origin: { lat: 48.8566, lng: 2.3522 }, // Paris
    });
  • getRequestParams(): Retrieves the current API request parameters being used by the instance.

    const currentRequestParams = autocomplete.getRequestParams();
    console.log("Current API Request Params:", currentRequestParams);
  • setOptions(options): Dynamically updates the UI behavior and appearance options of the widget. This allows you to change things like the placeholder text, debounce timing, or CSS classes after initialisation.

    • options (object): An object containing the UI and behavior options to update. These will be merged with existing options. Refer to the "UI & Behavior Options (options)" section for available options.
    // Example: Change the placeholder text and debounce time
    autocomplete.setOptions({
      placeholder: "Search for a location in France...",
      debounce: 250,
    });
    
    // Example: Update CSS classes for the input
    autocomplete.setOptions({
      classes: {
        input: "new-custom-input-style",
      },
    });
  • getOptions(): Retrieves the current UI and behavior options being used by the instance.

    const currentOptions = autocomplete.getOptions();
    console.log("Current UI Options:", currentOptions);

Google Places API & Billing

  • This library uses the Google Maps JavaScript API (specifically the Places library). Usage is subject to Google's terms and pricing.
  • An API key enabled for the "Places API" (and "Maps JavaScript API") is required.
  • The library uses Session Tokens automatically to group Autocomplete requests, which can lead to significant cost savings compared to per-request billing. See Google's Session Token Pricing.
  • Place Details requests (made when a suggestion is selected to get displayName, formattedAddress, etc.) are billed separately. The library currently fetches displayName, formattedAddress, and addressComponents by default. This can be expanded if needed, but be mindful of Place Data Fields Pricing.

Testing

This project includes both unit tests (using Vitest) and end-to-end tests (using Playwright).

Unit Tests

Unit tests are located in the tests/ directory and are run using Vitest. To execute the unit tests, use the following command:

npm run test:vitest

End-to-End Tests

End-to-end tests are located in the e2e/ directory and are run using Playwright. To execute the end-to-end tests, ensure your development server is running (e.g., npm run dev) and then use the following command:

npm run test:e2e

Contributing

Contributions are welcome! Please feel free to open an issue or submit a pull request.

License

MIT

About

A flexible and customizable vanilla JavaScript library leveraging the Google Maps Places (New) Autocomplete API. This library provides a user-friendly way to search for and retrieve detailed address information in any web application.

Topics

Resources

License

MIT, MIT licenses found

Licenses found

MIT
LICENCE
MIT
LICENSE

Stars

Watchers

Forks

Packages

No packages published