Usage

There are two ways in which leaflet-geosearch can be used. Direct usage, for example for address forms, or embedded in a leaflet map to search for points of interest.

Using the providers directly

All providers can be used without leaflet. You might want to bind them to a form;

import { OpenStreetMapProvider } from 'leaflet-geosearch';

const provider = new OpenStreetMapProvider();
const results = await provider.search({ query: input.value });

Reverse geocoding

reverse returns the places at a position, closest first, in the same format as search:

const provider = new OpenStreetMapProvider();
const [place] = await provider.reverse({ lat: 52.3731, lng: 4.8926 });

console.log(
  JSON.stringify({ label: place.label, x: place.x, y: place.y }, null, 2),
);
{
  "label": "Dam, Centrum, Amsterdam, Noord-Holland, Nederland, 1012 NP, Nederland",
  "x": 4.8926932,
  "y": 52.3733144
}

OpenStreetMap, LocationIQ, CivilDefenseMap, Photon, Pelias, Geocode Earth, Geoapify, GeoApiFr and PdokNl support it. The other providers reject with "This provider does not support reverse geocoding".

leaflet-geosearch imports Leaflet, which only runs in a browser. For server-side rendering (Next.js, Nuxt, ...), import the providers from leaflet-geosearch/providers. It has the same providers and doesn't import Leaflet:

import { OpenStreetMapProvider } from 'leaflet-geosearch/providers';

Using the leaflet control

Or add the GeoSearchControl to the leaflet map instance, to render a search control on your map;

See Leaflet Control for more info about the the options this control provides.

import { GeoSearchControl, OpenStreetMapProvider } from 'leaflet-geosearch';

const searchControl = new GeoSearchControl({
  provider: new OpenStreetMapProvider(),
  style: 'bar',
});

map.addControl(searchControl);

Leaflet 2

The control works with Leaflet 1.6 and up, and with Leaflet 2. Leaflet 2 has no factory functions like L.map() and no global L in its ES modules, so create the map with new Map() and import what you need by name. The control is used the same way:

import { Map, TileLayer } from 'leaflet';
import { GeoSearchControl, OpenStreetMapProvider } from 'leaflet-geosearch';

const map = new Map('map').setView([52.09, 5.12], 8);
new TileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);

map.addControl(new GeoSearchControl({ provider: new OpenStreetMapProvider() }));

Without a bundler, load Leaflet 2's leaflet-global.js, which sets window.L, before the UMD build of leaflet-geosearch:

<link
  rel="stylesheet"
  href="https://unpkg.com/[email protected]/dist/leaflet.css"
/>
<link
  rel="stylesheet"
  href="https://unpkg.com/leaflet-geosearch@5/dist/geosearch.css"
/>
<script src="https://unpkg.com/[email protected]/dist/leaflet-global.js"></script>
<script src="https://unpkg.com/leaflet-geosearch@5/dist/geosearch.umd.js"></script>

Leaflet 2 is only published as ES modules. The CommonJS build of leaflet-geosearch loads it with require('leaflet'), which works in Node 20.19+ and 22.12+.

Results

The search event of all providers return an array of result objects. The base structure is uniform between the providers. It contains objects matching the following interface:

interface result {
  x: number; // lon
  y: number; // lat
  label: string; // formatted address
  bounds: [
    [number, number], // south, west - lat, lon
    [number, number], // north, east - lat, lon
  ];
  raw: any; // raw provider result
}