How to Get an Address When a User Clicks a Map

API or service
Reverse Geocoding API + map library
Task
Map click → postal address
Examples
MapLibre GLLeafletOpenLayers
Difficulty
Intermediate
Time
10 min

A user clicks a location on an interactive map, and the application needs to show the address at that point. The map provides geographic coordinates, but it does not provide a postal address.

Listen for the map library’s click event, normalize the clicked latitude and longitude, and send them to the Geoapify Reverse Geocoding API. Display the returned formatted address or use individual fields such as street, city, and postcode.

Create a reverse-geocoding helper

Define the API request once and reuse it with MapLibre GL, Leaflet, and OpenLayers. The normalization helpers keep longitude within [-180, 180) and latitude within [-90, 90], which are the ranges accepted by the Reverse Geocoding API.

const apiKey = "YOUR_API_KEY";
const addressOutput = document.querySelector("#address-output");

function normalizeLongitude(longitude) {
  return ((((longitude + 180) % 360) + 360) % 360) - 180;
}

function clampLatitude(latitude) {
  return Math.max(-90, Math.min(90, latitude));
}

async function getAddressAt(longitude, latitude) {
  const params = new URLSearchParams({
    lon: String(longitude),
    lat: String(latitude),
    format: "json",
    apiKey
  });

  const response = await fetch(
    `https://api.geoapify.com/v1/geocode/reverse?${params}`
  );

  if (!response.ok) {
    throw new Error(`Reverse geocoding failed: ${response.status}`);
  }

  const data = await response.json();
  return data.results[0]?.formatted ?? "No address found";
}

getAddressAt() returns a display-ready address or "No address found". The map-specific handlers below normalize their coordinates before passing them to this function.

Add an output element near the map so users can see the loading state and returned address:

<p id="address-output">Click the map to get an address.</p>

Handle map clicks with MapLibre GL

MapLibre exposes the clicked longitude and latitude through event.lngLat. Normalize both values before calling the shared helper; longitude wrapping is especially useful when the map displays repeated world copies.

map.on("click", async (event) => {
  const longitude = normalizeLongitude(event.lngLat.lng);
  const latitude = clampLatitude(event.lngLat.lat);

  addressOutput.textContent = "Loading address…";
  addressOutput.textContent = await getAddressAt(longitude, latitude);
});

The example uses MapLibre’s click event and the shared normalizeLongitude(), clampLatitude(), and getAddressAt() functions. It assumes that map is an initialized MapLibre GL map. See the MapLibre map setup guide.

Handle map clicks with Leaflet

Leaflet exposes the clicked position through event.latlng. Although Leaflet normally supplies valid geographic coordinates, normalize them before sending the API request so the same boundary handling is used by every map integration.

map.on("click", async (event) => {
  const longitude = normalizeLongitude(event.latlng.lng);
  const latitude = clampLatitude(event.latlng.lat);

  addressOutput.textContent = "Loading address…";
  addressOutput.textContent = await getAddressAt(longitude, latitude);
});

The example uses Leaflet’s click event and the shared normalization and reverse-geocoding helpers. It assumes that map is an initialized Leaflet map. See the Leaflet map setup guide.

Handle map clicks with OpenLayers

OpenLayers maps commonly use Web Mercator coordinates. First convert the clicked coordinate to geographic longitude and latitude with toLonLat(), then normalize those values before calling the shared helper.

import { toLonLat } from "ol/proj.js";

map.on("singleclick", async (event) => {
  const [rawLongitude, rawLatitude] = toLonLat(event.coordinate);
  const longitude = normalizeLongitude(rawLongitude);
  const latitude = clampLatitude(rawLatitude);

  addressOutput.textContent = "Loading address…";
  addressOutput.textContent = await getAddressAt(longitude, latitude);
});

The example uses OpenLayers’ singleclick event, toLonLat(), and the shared normalization and reverse-geocoding helpers. It assumes that map is initialized. See the OpenLayers map setup guide.

Production checklist

  • Show a loading state because reverse geocoding is asynchronous.
  • Handle clicks where no address is available, such as remote or offshore locations.
  • Debounce or cancel earlier requests if the user clicks repeatedly.
  • Normalize longitude to [-180, 180) and clamp latitude to [-90, 90] before every request.
  • Keep longitude and latitude ordering explicit. Map libraries often expose [longitude, latitude], while the API uses separate lon and lat parameters.
  • Restrict browser API keys to the origins that are allowed to use them.