DEV Community

Cover image for Leaflet Address Autocomplete with Geoapify (Companion to MapLibre Example)
Casey Rivers for Geoapify Maps API

Posted on

Leaflet Address Autocomplete with Geoapify (Companion to MapLibre Example)

This is the Leaflet version of our 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.

Try the live demo:

➑️ View on CodePen

APIs used:


🧭 Table of Contents

  1. Leaflet vs MapLibre: Which Should You Choose?
  2. Set Up a Leaflet Map
  3. Add the Address Autocomplete Field
  4. Sync Selection with Leaflet Map
  5. Explore the Demo
  6. Summary
  7. FAQ

Leaflet vs MapLibre: Which Should You Choose?

Both Leaflet and MapLibre GL work seamlessly with Geoapify's Address Autocomplete. The choice depends on your project requirements:

Feature Leaflet MapLibre GL
Tile format Raster (PNG) Vector (MVT) + WebGL
Bundle size ~42 KB gzip ~258 KB gzip
Coordinate order [lat, lng] [lng, lat] (GeoJSON)
3D/Terrain support ❌ No βœ… Yes
Zoom behavior Raster tile zoom levels Continuous vector re-rendering
Basemap styling Swap tile layers Full runtime control (style spec)
Learning curve Easier Moderate
Best for Lightweight raster maps, UI overlays Vector maps, smooth camera, 3D terrain

Choose Leaflet if you need a lightweight solution with raster tiles and flexible overlay styling (markers, popups, polylines).

Choose MapLibre GL if you want vector maps with smooth camera animations, runtime basemap styling, or 3D terrain.

πŸ“– See the MapLibre version: Add Address Autocomplete to a MapLibre GL Map with Click-to-Address Reverse Geocoding

The autocomplete widget code is identical for both libraries - only the map integration differs.


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:

<!-- Leaflet CSS -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />

<!-- Leaflet JS -->
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
Enter fullscreen mode Exit fullscreen mode

Create the map container

<div id="map"></div>
Enter fullscreen mode Exit fullscreen mode

Style it to fill the viewport:

html, body, #map {
  width: 100%;
  height: 100%;
  margin: 0;
}
Enter fullscreen mode Exit fullscreen mode

Initialize the map

Create a Leaflet map with Geoapify tile layer:

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 <a href="https://www.geoapify.com/" target="_blank">Geoapify</a> | Β© OpenMapTiles Β© OpenStreetMap contributors',
  apiKey: myAPIKey,
  maxZoom: 20
}).addTo(map);

// Add zoom control to bottom-right
L.control.zoom({ position: "bottomright" }).addTo(map);
Enter fullscreen mode Exit fullscreen mode

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 geoapify.com to get a free API key.

Leaflet map centered on Washington DC with zoom controls

A 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

<!-- Geoapify Geocoder Autocomplete CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@geoapify/geocoder-autocomplete@3.0.1/styles/minimal.css" />

<!-- Geoapify Geocoder Autocomplete JS -->
<script src="https://cdn.jsdelivr.net/npm/@geoapify/geocoder-autocomplete@3.0.1/dist/index.min.js"></script>
Enter fullscreen mode Exit fullscreen mode

Create the autocomplete container

Position it over the map:

<div class="autocomplete-panel">
  <div id="autocomplete" class="autocomplete-container"></div>
</div>
Enter fullscreen mode Exit fullscreen mode
.autocomplete-panel {
  position: absolute;
  top: 10px;
  left: 10px;
  width: 400px;
  z-index: 1002;
}
Enter fullscreen mode Exit fullscreen mode

Initialize the autocomplete widget

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

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]
});
Enter fullscreen mode Exit fullscreen mode

The iconAnchor defines which point of the icon corresponds to the marker's coordinates. 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]);
  }
});
Enter fullscreen mode Exit fullscreen mode

Note the coordinate order difference: 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

  1. Type an address β†’ Select from dropdown β†’ Map pans and marker appears
  2. 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}"
  }
};
Enter fullscreen mode Exit fullscreen mode

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:

  1. Leaflet map - raster tiles with retina support
  2. Address autocomplete - same Geoapify widget as MapLibre
  3. Custom marker - using the Marker Icon API

The main differences from MapLibre:

  • Leaflet uses raster tiles (PNG), MapLibre uses vector tiles
  • Coordinate order: Leaflet is [lat, lon], MapLibre is [lon, lat]
  • Marker API: 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. For example: filter: { countrycode: ["us", "ca"] } limits results to USA and Canada. See the Address Autocomplete API docs.

Q: Can I use the autocomplete with React or Angular?

A: Yes. We provide dedicated wrapper libraries:

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.

Top comments (0)