Skip to content

Autocomplete Search Box for MapLibre GL JS

Add an autocomplete search box to your map with just a few lines of code. Our plugin takes care of all the UI and API calls for you, and implements best practices including debouncing of requests, caching of recent results, and zooming the map to the results when the user makes a selection.

Quickstart with npm

Installation

First, install the package via your favorite package manager.

npm install --save @stadiamaps/maplibre-search-box
yarn add @stadiamaps/maplibre-search-box

You can now use this in your JS or TS project just like any other package!

Example code

import { MapLibreSearchControl } from "@stadiamaps/maplibre-search-box";
import "@stadiamaps/maplibre-search-box/dist/style.css";

const control = new MapLibreSearchControl({
    onResultSelected: feature => {
      // You can add code here to take some action when a result is selected.
      console.log(feature.geometry.coordinates);
    },
    // You can also use our EU endpoint to keep traffic within the EU using the basePath option:
    // baseUrl: "https://api-eu.stadiamaps.com",
});
const map = new maplibregl.Map({
  container: "map",
  style: "https://tiles.stadiamaps.com/styles/alidade_smooth.json", // stylesheet location
  center: [-74.5, 40], // starting position [lng, lat]
  zoom: 2, // starting zoom
});
map.addControl(control, "top-left");

Quickstart with unpkg

If you like to keep your frontend simple and don't want to use JS build tooling, we have you covered! You can easily use the plugin by linking to the module on unpkg. The library is exported via the global maplibreSearchBox, but otherwise functions exactly as if you used npm package tooling.

Try it in JSFiddle
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Basic MapLibre Search</title>
    <script src="https://unpkg.com/maplibre-gl@3.6.2/dist/maplibre-gl.js"></script>
    <link
      href="https://unpkg.com/maplibre-gl@3.6.2/dist/maplibre-gl.css"
      rel="stylesheet"
    />
    <script src="https://unpkg.com/@stadiamaps/maplibre-search-box/dist/maplibre-search-box.umd.js"></script>
    <link
      href="https://unpkg.com/@stadiamaps/maplibre-search-box/dist/style.css"
      rel="stylesheet"
    />
  </head>
  <body style="margin: 0; padding: 0">
    <div id="map" style="height: 100vh; width: 100vw"></div>
    <script type="application/javascript">
      var control = new maplibreSearchBox.MapLibreSearchControl({
        useMapFocusPoint: true,
        onResultSelected: feature => {
          // You can add code here to take some action when a result is selected.
          console.log(feature.geometry.coordinates);
        },
        // You can also use our EU endpoint to keep traffic within the EU using the basePath option:
        // baseUrl: "https://api-eu.stadiamaps.com",
      });
      var map = new maplibregl.Map({
        container: "map",
        // You can also use our EU endpoints here by changing the host to tiles-eu.stadiamaps.com
        style: "https://tiles.stadiamaps.com/styles/alidade_smooth.json", // stylesheet location
        center: [-74.5, 40], // starting position [lng, lat]
        zoom: 2, // starting zoom
      });
      map.addControl(control, "top-left");
    </script>
  </body>
</html>

Options

The MapLibreSearchControl constructor takes a set of options (as an object):

Options Overview

export class MapLibreSearchControlOptions {
  useMapFocusPoint = true;
  mapFocusPointMinZoom = 5;
  fixedFocusPoint: [number, number] = null;
  searchOnEnter = false;
  maxResults = 5;
  minInputLength = 3;
  minWaitPeriodMs = 100;
  layers: PeliasLayer[] = null;
  onResultSelected?: (feature: PeliasGeoJSONFeature) => void;
  baseUrl: string | null = null;
}

Options Detail

useMapFocusPoint

If set, the map center point is used to influence the search for better contextual results.

mapFocusPointMinZoom

On low zooms, the focus point is often unuseful for contextual results (e.g., on zoom 0, the whole world is visible, so the center is not valuable). This controls at what zoom the center is used to influence results.

fixedFocusPoint

A single point used to influence results (doesn't follow the map viewport).

searchOnEnter

For address-based forward geocoding applications, it often makes sense to use the forward geocoding (/search) endpoint rather than autocomplete search, once you know that the user has completed their input. The full forward geocoding endpoint is able to interpolate addresses, and may provide better results with complete input than the autocomplete endpoint. Opting in to this behavior will send a final forward geocoding request if the user presses enter.

Note

The /search endpoint is not available to all plans, so check if your plan supports /search before enabling this. You can find the full feature comparison on our pricing page.

maxResults

Maximum number of results to return.

minInputLength

Minimum number of characters to wait for before making the first search.

minWaitPeriodMs

The minimum time to wait between searches. Higher values decrease the number of API requests made, but increase the received latency of the input.

layers

Which layers to use in the search. Defaults to all layers. See the Layers documentation for more details.

Note: if you want the fastest possible search, but don't mind excluding addresses or Point of Interest (venue) results, use ['coarse'] for the best performance.

onResultSelected

A callback to be invoked whenever a result is selected by the user. This is invoked with a single argument, the PeliasFeature for the result. This allows you take an action (such as autofilling your own form).

baseUrl

An optional override to the base API URL. This defaults to the primary Stadia Maps API endpoint. If you want to use our EU endpoints to ensure traffic is handled by EU servers, set the baseUrl to https://api-eu.stadiamaps.com.

Source Code

Our MapLibre GL JS Search Box plugin is completely open source! You can find the source code on GitHub.