Leaflet Address Autocomplete with Geoapify (Companion to MapLibre Example)
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
- Address Autocomplete API – real‑time suggestions as users type
- Map Tiles – raster map tiles for Leaflet
- Map Marker Icon API – custom marker icons
🧭 Table of Contents
- Step 1: Set Up a Leaflet Map
- Step 2: Add the Address Autocomplete Field
- Step 3: Sync Selection with Leaflet Map
- Step 4: Explore the Demo
- Summary
- FAQ
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
@2xtiles are for retina displays.
🔑 API Key: Sign up at to get a free API key.

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.

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:
- A full‑screen Leaflet map.
- An autocomplete input in the top‑left corner.
- Real‑time address suggestions.
- 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].

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:
- Map Tiles Playground – try different map styles
- Marker Icon Playground – design custom markers
- Autocomplete Playground – test address search
Try It Now
Sign up at geoapify.com and get your free API key to start building Leaflet maps with address autocomplete.