Leaflet Address Autocomplete with Geoapify (Companion to MapLibre Example)

Published: (December 25, 2025 at 12:58 AM EST)
6 min read
Source: Dev.to

Source: Dev.to

Leaflet version of the Address Autocomplete example

If you’ve seen the MapLibre GL tutorial, this follows the same UX pattern: users can search for an address and see it on an interactive map with a marker.

APIs used

🧭 Table of Contents

Step 1: Set Up a Leaflet Map

Start by loading Leaflet and initializing a map with Geoapify raster tiles.

Include Leaflet

Add the CSS and JavaScript from a CDN:

Create the map container

Style the container

html, body, #map {
  width: 100%;
  height: 100%;
  margin: 0;
}

Initialize the map

const myAPIKey = "YOUR_API_KEY";

const map = L.map("map", { zoomControl: false }).setView(
  [38.908838755401035, -77.02346458179596], // Washington DC
  12
);

// Retina displays require different tile quality
const isRetina = L.Browser.retina;

const baseUrl   = "https://maps.geoapify.com/v1/tile/osm-bright/{z}/{x}/{y}.png?apiKey={apiKey}";
const retinaUrl = "https://maps.geoapify.com/v1/tile/osm-bright/{z}/{x}/{y}@2x.png?apiKey={apiKey}";

L.tileLayer(isRetina ? retinaUrl : baseUrl, {
  attribution: 'Powered by [Geoapify](https://www.geoapify.com/) | © OpenMapTiles © OpenStreetMap contributors',
  apiKey: myAPIKey,
  maxZoom: 20
}).addTo(map);

// Add zoom control to bottom‑right
L.control.zoom({ position: "bottomright" }).addTo(map);

Note: Leaflet uses raster (PNG) tiles, while MapLibre uses vector tiles. Geoapify provides both formats. The @2x tiles are for retina displays.

🔑 API Key: Sign up at to get a free API key.

Leaflet map centered on Washington DC with zoom controls
Leaflet map initialized with Geoapify raster tiles.

Step 2: Add the Address Autocomplete Field

The autocomplete setup is identical to the MapLibre example.

Include the Geocoder Autocomplete library

Create the autocomplete container


  
.autocomplete-panel {
  position: absolute;
  top: 10px;
  left: 10px;
  width: 400px;
  z-index: 1002;
}

Initialize the autocomplete widget

const autocompleteInput = new autocomplete.GeocoderAutocomplete(
  document.getElementById("autocomplete"),
  myAPIKey,
  { /* options */ }
);

The GeocoderAutocomplete widget works the same way regardless of which map library you use.

Address autocomplete dropdown showing suggestions over the Leaflet map
The autocomplete dropdown appears as the user types.

Step 3: Sync Selection with Leaflet Map

When the user selects an address, pan the map and place a marker.

Create a custom marker icon

Use the Geoapify Map Marker Icon API to generate a custom pin:

const markerIcon = L.icon({
  iconUrl: `https://api.geoapify.com/v1/icon/?type=awesome&color=%232ea2ff&size=large&scaleFactor=2&apiKey=${myAPIKey}`,
  iconSize: [38, 56],
  iconAnchor: [19, 51],
  popupAnchor: [0, -60]
});

The iconAnchor defines which point of the icon corresponds to the marker’s coordinates.

Add the marker on selection

let marker; // will hold the current marker

autocompleteInput.on("select", (place) => {
  const { lat, lon } = place.properties;

  // Pan the map to the selected location
  map.setView([lat, lon], 15);

  // Remove previous marker, if any
  if (marker) {
    map.removeLayer(marker);
  }

  // Add new marker
  marker = L.marker([lat, lon], { icon: markerIcon }).addTo(map);
});

Now the map automatically centers on the chosen address and displays a custom marker.

Step 4: Explore the Demo

Copy the full HTML/JS code into a file (e.g., leaflet-autocomplete.html) and open it in a browser.
You should see:

  1. A full‑screen Leaflet map.
  2. An autocomplete input in the top‑left corner.
  3. Real‑time address suggestions.
  4. Automatic panning and a custom marker when an address is selected.

Summary

  • Leaflet + Geoapify raster tiles → simple, lightweight map.
  • Address Autocomplete API provides instant suggestions.
  • Map Marker Icon API lets you style the marker to match your design.
  • The same autocomplete widget works across different map libraries, making it easy to switch between Leaflet, MapLibre, Mapbox GL, etc.

FAQ

Q: Do I need a paid plan for the raster tiles?
A: No. The free tier includes a generous number of raster tile requests per month.

Q: Can I change the marker color?
A: Yes. Adjust the color parameter in the icon URL (hex value, e.g., %23ff0000 for red).

Q: How do I restrict autocomplete results to a specific country?
A: Pass the filter option when initializing the widget, e.g., { filter: "countrycode:us" }.

Q: What if I want to use a different map style?
A: Replace the baseUrl/retinaUrl with another Geoapify style (e.g., osm-dark, osm-light).

Feel free to experiment and adapt the code to your own project!

Note: For a pin icon, this should be near the bottom tip.

Handle the select event

let marker;

autocompleteInput.on("select", (location) => {
  // Remove existing marker
  if (marker) {
    marker.remove();
  }

  if (location) {
    // Add marker at the selected location
    marker = L.marker([location.properties.lat, location.properties.lon], {
      icon: markerIcon
    }).addTo(map);

    // Pan to the selected location
    map.panTo([location.properties.lat, location.properties.lon]);
  }
});

Note: Leaflet uses [lat, lon] while MapLibre uses [lon, lat].

Leaflet map with marker placed at selected address location

After selecting an address, the map pans to the location and displays a marker.

Step 4: Explore the Demo

The live CodePen demo shows the complete implementation.

Try these flows

  • Type an address → Select from dropdown → Map pans and marker appears
  • Try different themes → Use the theme selector to switch light/dark modes

Theme switcher

The demo includes a theme selector that switches both the autocomplete style and map tiles:

const mapTiles = {
  light: {
    baseUrl: "https://maps.geoapify.com/v1/tile/osm-bright/{z}/{x}/{y}.png?apiKey={apiKey}",
    retinaUrl: "https://maps.geoapify.com/v1/tile/osm-bright/{z}/{x}/{y}@2x.png?apiKey={apiKey}"
  },
  dark: {
    baseUrl: "https://maps.geoapify.com/v1/tile/dark-matter-brown/{z}/{x}/{y}.png?apiKey={apiKey}",
    retinaUrl: "https://maps.geoapify.com/v1/tile/dark-matter-brown/{z}/{x}/{y}@2x.png?apiKey={apiKey}"
  }
};

Want reverse geocoding?

For click‑to‑address functionality (clicking on the map to get an address), see the MapLibre GL tutorial.
The same Reverse Geocoding API call works with Leaflet—just replace the MapLibre marker code with Leaflet’s L.marker().

👉 Try it in the interactive demo.

Summary

You’ve built a Leaflet map with address autocomplete:

  • Leaflet map – raster tiles with retina support
  • Address autocomplete – same Geoapify widget as MapLibre
  • Custom marker – using the Marker Icon API

Main differences from MapLibre

  • Leaflet uses raster (PNG) tiles; MapLibre uses vector tiles.
  • Coordinate order: Leaflet [lat, lon], MapLibre [lon, lat].
  • Marker creation: L.marker() vs. maplibregl.Marker().

Useful links

FAQ

Q: What’s the difference between Leaflet and MapLibre?
A: Leaflet uses raster (PNG) tiles and is lighter weight. MapLibre uses vector tiles, supports 3D, and offers smoother zooming. Both work great with Geoapify APIs.

Q: How do I restrict autocomplete results to a specific country?
A: Use the filter option with countrycode, rect (bounding box), or circle parameters. Example:

filter: { countrycode: ["us", "ca"] }

Limits results to the USA and Canada. See the Address Autocomplete API docs.

Q: Can I use the autocomplete with React or Angular?
A: Yes. Dedicated wrapper libraries are available:

Q: How can I experiment with these APIs before coding?
A: Use our interactive playgrounds:

Try It Now

👉 Open the Live Demo

Sign up at geoapify.com and get your free API key to start building Leaflet maps with address autocomplete.

Back to Blog

Related posts

Read more »