npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

places-autocomplete-svelte

v2.2.20

Published

A flexible, accessible, and secure Svelte component leveraging the Google Maps Places Autocomplete API (New) to provide a user-friendly way to search for and retrieve detailed address information.

Readme

Places (New) Autocomplete Svelte

npm version License: MIT

A flexible, accessible, and secure Svelte component leveraging the Google Maps Places Autocomplete API (New).

The component handles API loading, session tokens, debounced fetching, and accessibility, allowing you to focus on building your application. It intelligently manages the Google Maps API loader, creating a shared instance via Svelte's context that prevents conflicts with other map components on the same page.

Two initialisation patterns:

  • Simple/Automatic: Pass your API key directly to the component for basic use cases
  • Advanced/Manual: Initialise the loader once in a parent component when using multiple Google Maps libraries or components

Available: Standalone JavaScript Library

Need this functionality for a non-Svelte project? Check out our companion vanilla JavaScript library, places-autocomplete-js, which offers the same core Google Places (New) Autocomplete features. View places-autocomplete-js on GitHub

Features

  • Integrates with the modern Google Maps Places Autocomplete API (New).
  • Automatic Shared Loader: Intelligently creates a single Google Maps loader instance and shares it via Svelte's context.
  • Highly Accessible: Follows WAI-ARIA patterns for comboboxes, with full keyboard navigation and screen reader support.
  • Secure: Safely renders suggestions to protect against XSS attacks.
  • Automatically handles session tokens for cost management.
  • Debounced Input: Limits API calls while the user is typing (configurable).
  • Suggestion Highlighting: Automatically highlights the portion of text matching the user's input.
  • Imperative API: Exposes clear(), focus(), and getRequestParams() methods for direct control.
  • Customisable Styling: Easily override default styles using the options.classes prop.
  • TypeScript Support: Fully written in TypeScript with included type definitions.
  • Event Handling: Provides onResponse and onError callbacks.

Demo

See a live demo of the component in action: Basic Example

Reactive parameters - change the search criteria based on user input, like filtering by country or change results language.

Customise request parameters - construct a requestParams object and control various aspects of the search, including language, region, and more.

Retain Input Value After Selection - This example demonstrates how to configure the component to keep the selected address visible in the input field after a suggestion is chosen.

Requirements

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

Installation

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

Usage

Basic Usage (Automatic Initialisation)

For simple use cases, just pass your API key to the component. It will automatically handle the Google Maps loader initialisation:

<script lang="ts">
    import { PlaceAutocomplete } from 'places-autocomplete-svelte';
    import type { PlaceResult } from 'places-autocomplete-svelte/interfaces';

    // Get API Key securely (e.g., from environment variables)
    const PUBLIC_GOOGLE_MAPS_API_KEY = import.meta.env.VITE_PUBLIC_GOOGLE_MAPS_API_KEY;

    const handleResponse = (response: PlaceResult) => {
        console.log('Selected:', response.formattedAddress);
    };

    const handleError = (error: string) => {
        console.error('Error:', error);
    };
</script>

<PlaceAutocomplete 
    {PUBLIC_GOOGLE_MAPS_API_KEY}
    onResponse={handleResponse} 
    onError={handleError} 
/>

Advanced Usage (Manual Initialisation)

For applications that need multiple Google Maps libraries (e.g., places, maps, marker) or multiple map components, initialise the loader once in a parent component. This approach:

  • Loads all required libraries in a single API call (more efficient)
  • Prevents "Loader must not be called again" errors
  • Shares the loader instance across all child components via Svelte context
  • Works seamlessly with SvelteKit's SSR (only initialises in the browser)

When to use manual initialisation:

  • Using multiple Google Maps components on the same page
  • Need to load multiple libraries (maps, marker, geometry, etc.)
  • Building a layout that shares map functionality across routes
  • Want centralised error handling for the loader
// In +layout.svelte or +page.svelte
<script lang="ts">
    import { browser } from '$app/environment';
    import { PlaceAutocomplete } from 'places-autocomplete-svelte';
    import { setGMapsContext, initialiseGMaps, importLibrary } from 'places-autocomplete-svelte/gmaps';
    import { onMount } from 'svelte';

    // 1. Set the context at the top level (must be synchronous)
    setGMapsContext();

    // 2. Initialise the loader in the browser
    if (browser) {
        initialiseGMaps({
            key: import.meta.env.VITE_PUBLIC_GOOGLE_MAPS_API_KEY,
            v: 'weekly'
        }).catch((error) => {
            console.error('Failed to initialise Google Maps:', error);
        });
    }

    // 3. Load additional libraries as needed
    let map: google.maps.Map;
    
    onMount(async () => {
        const { Map } = await importLibrary('maps');
        const { AdvancedMarkerElement } = await importLibrary('marker');
        
        const mapElement = document.getElementById('map');
        if (mapElement) {
            map = new Map(mapElement, {
                center: { lat: 51.5072, lng: -0.1276 },
                zoom: 10,
                mapId: 'YOUR_MAP_ID'
            });
        }
    });

    // 4. Handle autocomplete responses
    const handleResponse = (response: PlaceResult) => {
        console.log('Selected:', response.formattedAddress);
        // Update map with selected location
        if (response.location && map) {
            map.setCenter(response.location);
            map.setZoom(15);
        }
    };

    const handleError = (error: string) => {
        console.error('Error:', error);
    };
</script>

<!-- The component automatically uses the shared context -->
<!-- No need to pass PUBLIC_GOOGLE_MAPS_API_KEY when using manual initialisation -->
<PlaceAutocomplete 
    onResponse={handleResponse} 
    onError={handleError} 
/>

<div id="map" class="h-96 w-full"></div>

Available helper functions from places-autocomplete-svelte/gmaps:

  • setGMapsContext() - Creates the shared context (call once at the top level)
  • getGMapsContext() - Retrieves the context (returns stores for initialisation state and errors)
  • hasGMapsContext() - Checks if context exists (useful for conditional logic)
  • initialiseGMaps(options) - Initialises the loader with your API key and options
  • initialiseGMapsNoContext(options) - Initialises without context (for edge cases)
  • importLibrary(library) - Dynamically imports Google Maps libraries

Security

API Key Security

Your Google Maps API Key is a sensitive credential. To prevent unauthorised use and unexpected charges, you must restrict it.

  1. Go to the Google Cloud Console.
  2. Select your API key.
  3. Under Application restrictions, select HTTP referrers (web sites) and add your application's domain(s) (e.g., your-domain.com/*).
  4. Under API restrictions, select Restrict key and choose the APIs you are using (e.g., Places API, Maps JavaScript API).

XSS Protection

This component is designed to be secure out-of-the-box. It safely renders user-input and API responses to prevent Cross-Site Scripting (XSS) vulnerabilities.

Accessibility

This component is built to be accessible and follows the WAI-ARIA Authoring Practices for a Combobox.

  • Keyboard Navigation: Users can navigate suggestions using ArrowUp, ArrowDown, select with Enter, and close the list with Escape.
  • Screen Reader Support: Uses role="combobox", aria-autocomplete, aria-expanded, and aria-activedescendant to provide a clear experience for screen reader users.
  • Focus Management: Focus remains on the input field while navigating the suggestion list.

Props

| Prop | Type | Required | Default | Description | | :--- | :--- | :--- | :--- | :--- | | PUBLIC_GOOGLE_MAPS_API_KEY | string | No* | - | Your Google Maps API Key. Required for automatic initialisation. Optional if you've initialised the loader in a parent component using initialiseGMaps(). | | onResponse | (response: PlaceResult) => void | Yes | - | Callback triggered when a user selects a place. Receives the full place details object. | | onError | (error: string) => void | Yes | - | Callback triggered when an error occurs (API loading, network issues, etc.). | | fetchFields | string[] | No | ['formattedAddress', 'addressComponents'] | Place Data Fields to request from the API. See Place Data Fields. Affects API billing. | | requestParams | Partial<RequestParams> | No | { inputOffset: 3 } | Parameters for the Autocomplete API request (language, region, location bias, etc.). See RequestParams interface. | | options | Partial<ComponentOptions> | No | { debounce: 100 } | UI and behavior options (placeholder, debounce delay, distance display, custom classes, etc.). See ComponentOptions interface. |

*Either PUBLIC_GOOGLE_MAPS_API_KEY prop OR manual initialisation with initialiseGMaps() is required.

Component Methods (Imperative API)

Get a reference to the component instance using bind:this to call its methods directly.

Example:

<script lang="ts">
    import PlaceAutocomplete from 'places-autocomplete-svelte';
    let autocompleteComponent: PlaceAutocomplete | undefined = $state(undefined);
</script>

<PlaceAutocomplete bind:this={autocompleteComponent} ... />

<button onclick={() => autocompleteComponent?.clear()}>Clear</button>
<button onclick={() => autocompleteComponent?.focus()}>Focus</button>

| Method | Signature | Description | | :--- | :--- | :--- | | clear() | () => void | Clears the input, removes suggestions, and resets the session token. | | focus() | () => void | Sets focus on the text input field. | | getRequestParams() | () => RequestParams | Returns the current internal requestParams object. |

Options

| Option | Type | Default | Description | | :--- | :--- | :--- | :--- | | placeholder | string | '' | Placeholder text for the input field. | | debounce | number | 100 | Delay in ms before firing API request. Set to 0 to disable. | | distance | boolean | true | Show distance from requestParams.origin (if provided). | | distance_units | 'km' \| 'miles' | 'km' | Units for displaying distance. | | label | string | '' | Optional label text displayed above the input. | | autofocus | boolean | false | Automatically focus the input on mount. | | autocomplete | string | 'off' | The autocomplete attribute for the input field. | | classes | Partial<ComponentClasses> | {} | Object to override default CSS classes. See Styling section. | | clear_input | boolean | true | If false, retains the formattedAddress in the input after selection. |

Styling (options.classes)

Customise the component by providing your own CSS classes via options.classes.

Available Class Keys:

  • section: The main container section.
  • container: The div containing the input and suggestions list.
  • label: The label element.
  • 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 <li>.
  • li_div_container: Container div within each list item.
  • li_div_one: First inner div (contains the main text).
  • li_div_one_p: The <p> tag containing the main suggestion text.
  • li_div_two: Second inner div (contains the distance).
  • li_div_two_p: The <p> tag containing the distance text.
  • kbd_container: Container for the keyboard hint keys.
  • 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. Defaults to 'font-bold'.

Example:

const options = {
  classes: {
    input: 'form-input w-full rounded-md shadow-sm',
    ul: 'absolute bg-white shadow-lg rounded-md mt-1 w-full z-10',
    li_current: 'bg-blue-500 text-white',
    highlight: 'text-blue-700 font-semibold'
  }
};

Events

  • onResponse: (response: PlaceResult) => void
    • Fired after a user selects a suggestion and fetchFields are retrieved.
  • onError: (error: string) => void
    • Fired on any error (API loading, fetching suggestions, etc.).

TypeScript

This component is written in TypeScript with full type definitions included.

Available imports:

// Component
import { PlaceAutocomplete } from 'places-autocomplete-svelte';

// Types and interfaces
import type { 
    PlaceResult,
    ComponentOptions,
    RequestParams,
    FormattedAddress,
    ComponentClasses,
    Props
} from 'places-autocomplete-svelte/interfaces';

// Google Maps loader helpers
import { 
    setGMapsContext,
    getGMapsContext,
    hasGMapsContext,
    initialiseGMaps,
    initialiseGMapsNoContext,
    importLibrary,
    type GMapsContext,
    type APIOptions
} from 'places-autocomplete-svelte/gmaps';

Google Places API & Billing

  • This component uses the Google Maps JavaScript API (Places library). Usage is subject to Google's terms and pricing.
  • It uses Session Tokens automatically to group Autocomplete requests, which can reduce costs.
  • Place Details requests (via fetchFields) are billed separately. Only request the fields you need to manage costs.

Contributing

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

License

MIT