MapSnippets logoMapSnippets logo

Address Search with Leaflet

Leaflet

Add an autocomplete address search dropdown to a Leaflet map using the MapTiler Geocoding API.

progress_activityLoading map...
const map = L.map('map').setView([48.8566, 2.3522], 5);
L.tileLayer('https://api.maptiler.com/maps/streets-v4/256/{z}/{x}/{y}.png?key=YOUR_MAPTILER_KEY', {
  tileSize: 256,
  attribution: '&copy; <a href="https://www.maptiler.com/">MapTiler</a> &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap contributors</a>'
}).addTo(map);
let marker, timeout;
const input = document.getElementById('search-box');
const results = document.getElementById('results');
input.addEventListener('input', () => {
  clearTimeout(timeout);
  const q = input.value.trim();
  if (q.length < 3) { results.style.display = 'none'; return; }
  timeout = setTimeout(async () => {
    const res = await fetch('https://api.maptiler.com/geocoding/' + encodeURIComponent(q) + '.json?key=YOUR_MAPTILER_KEY&limit=5');
    const data = await res.json();
    results.innerHTML = '';
    results.style.display = data.features.length ? 'block' : 'none';
    data.features.forEach(f => {
      const div = document.createElement('div');
      div.textContent = f.place_name;
      div.onclick = () => {
        const [lng, lat] = f.center;
        if (marker) marker.remove();
        marker = L.marker([lat, lng]).addTo(map).bindPopup(f.place_name).openPopup();
        map.setView([lat, lng], 14);
        results.style.display = 'none';
        input.value = f.place_name;
      };
      results.appendChild(div);
    });
  }, 300);
});

How it works

The MapTiler Geocoding API converts an address string into geographic coordinates. As the user types (minimum 3 characters), a debounced request fires after 300ms of inactivity. The dropdown shows up to 5 matching results from the geocoding endpoint.

Clicking a result extracts the center coordinates in [lng, lat] order, swaps them to Leaflet’s [lat, lng] order, places a marker with a popup, and pans the map with setView(). The dropdown hides and the input updates with the selected place name.

Key APIs

API Description Docs
MapTiler Geocoding Forward geocoding endpoint docs.maptiler.com/cloud/api/geocoding
L.marker() Place result marker leafletjs.com/reference.html#marker
map.setView() Pan to coordinates leafletjs.com/reference.html#map-setview

FAQ

How do I limit results to a specific country?

Add &country=fr (ISO 3166-1 alpha-2 code) to the geocoding URL to restrict results to France.

How do I show multiple results as markers?

The autocomplete already fetches up to 5 features. To place all of them on the map, loop through data.features and create a marker for each instead of showing a dropdown.

Common mistakes

  • Forgetting to encodeURIComponent() the search query: special characters will break the URL
  • Using the geocoding response center as [lat, lng] directly: it is [lng, lat] (GeoJSON order)
  • Not removing the previous marker before adding a new one: stale markers accumulate on the map
auto_awesome

Build maps using Leaflet with AI

Generate code like this address search with leaflet example using the Leaflet skill in your IDE.