A store locator is the small feature every multi-branch business ends up needing: the "find your nearest store" box that turns a postcode into a short, ranked list of shops on a map. It looks trivial from the outside, and the happy path is genuinely simple, but a good one quietly does three jobs well: it understands messy location input, it ranks branches by real proximity, and it renders the result on a map a human can act on.
This guide walks through how a store locator actually works, the four steps to build one with a maps API, and the details that separate a demo from something you would ship. Every map in this article is rendered with the MapAtlas API itself.
What a Store Locator Actually Does
Strip away the styling and a store locator is a pipeline with three stages:
- Geocode the visitor's input. "1012 Amsterdam", "SW1A 1AA", or a shared GPS position all have to become a single latitude and longitude.
- Rank nearby stores. Given that coordinate and your list of branch locations, find the closest ones within a sensible radius.
- Render the results. Put the ranked stores on a map as markers, each with its address, opening hours, and a link to directions.
The map below is exactly that third stage, rendered with MapAtlas tiles: six branches in central Amsterdam pinned by distance from the visitor. Here they are supermarkets, but the map is identical whether the markers come from a POI dataset or from your own list of stores.

The colour order is the ranking. The visitor searched from the centre of the map, and the markers are the nearest branches in order, closest first.
Step 1: Geocode the Visitor's Input
The visitor types a postcode, a city, or a full address, and you need a coordinate. That is forward geocoding.
// Turn what the visitor types into a coordinate (autocomplete geocoding)
const res = await fetch(
`https://gateway.mapmetrics-atlas.net/autocomplete/` +
`?token=${API_TOKEN}&text=${encodeURIComponent(query)}` +
`&focus.point.lat=52.37&focus.point.lon=4.89` // bias toward your service area
);
const { features } = await res.json();
const [lon, lat] = features[0].geometry.coordinates; // [lon, lat]
const label = features[0].properties.label; // "Damrak, Amsterdam, North Holland, Netherlands"
Two details matter here. Pass a focus.point near your service area so "Cambridge" resolves to the right one, and handle the case where the visitor shares device GPS instead of typing: then you already have the coordinate and skip this step entirely.
Step 2: Rank Your Stores by Distance
Now you have the visitor's coordinate. The stores themselves are your own data: a list of branches, each with a latitude and longitude, that lives in your database. Ranking them is a straight-line (haversine) distance calculation, no API call needed:
// Your branches, each with a lat/lon. Rank by distance from the visitor.
const ranked = stores
.map(s => ({ ...s, distance_m: haversine(lat, lon, s.lat, s.lon) }))
.sort((a, b) => a.distance_m - b.distance_m)
.slice(0, 6);
That is all a basic locator needs. For a large network you would first filter to a bounding box around the visitor so you are not measuring distance to every branch on every request, then sort the survivors. The output is a short list of the nearest branches, each with a distance_m.
Step 3: Rank by Distance, Then Refine by Travel Time
Straight-line distance is the right default. It is fast, it needs no extra call, and for a dense network it is usually correct. But the nearest shop as the crow flies is not always the fastest to reach: a store 400 metres away across a river can be a ten-minute detour to the nearest bridge.
For a locator where "nearest" really means "quickest to get to", re-rank the top few candidates by real travel time using a directions or matrix call:
// Re-rank the closest stores by real drive time (MapAtlas Matrix API)
const res = await fetch(`https://gateway.mapmetrics-atlas.net/matrix/?token=${API_TOKEN}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
sources: [{ lat, lon }],
targets: top3.map(s => ({ lat: s.lat, lon: s.lon })),
costing: 'auto', // 'auto' | 'bicycle' | 'pedestrian'
}),
});
const { sources_to_targets } = await res.json();
const row = sources_to_targets[0]; // one entry per target, each with .time (seconds)
const byTime = top3
.map((s, i) => ({ ...s, time: row[i].time }))
.sort((a, b) => a.time - b.time);
You only do this for the handful of nearest candidates, so it stays a single cheap call, not one per store.
Step 4: Render the Stores on a Map
The final step is the map itself. Drop a marker for each ranked store, add a popup with the address and opening hours, and frame the view so every result is visible. With a maps API that serves tiles, geocoding, and search from one provider, the whole locator is one vendor and one coordinate system end to end, which is what the map earlier in this article is built on.
Give each marker a popup with the essentials a visitor needs to act: name, address, distance, opening hours, and a "Directions" link that hands the coordinate to a routing engine.
Details That Separate a Demo from Production
Empty results. Someone searches from a region where you have no branches. Decide upfront whether to widen the radius automatically, show the single nearest store however far it is, or say "no stores within 50 km" honestly.
Opening hours. A locator that shows a shop as the nearest option when it is closed is frustrating. Filter or flag by opening hours so "open now" is a first-class option.
Ambiguous input. "Cambridge" exists in England and Massachusetts; "Springfield" exists dozens of times. Country biasing on the geocode step removes most of this, and offering autocomplete as the visitor types removes the rest.
Mobile GPS and consent. On mobile, the strongest experience is the "use my location" button, but reading device GPS is location data and needs consent. Ask first, and fall back to text input if the visitor declines.
Privacy. The visitor's location is personal data the moment it is tied to them. Geocode on demand, avoid storing the raw coordinate, and use an EU-based API so the location never leaves the EEA. See our guide to GDPR-compliant maps for the full picture.
Building a Store Locator with MapAtlas
MapAtlas gives you the whole pipeline from one API and one coordinate system. The Geocoding API turns postcodes and cities into coordinates with country biasing; you rank your own branch list against that coordinate; the Directions and Matrix APIs re-rank the top candidates by real travel time; and the Dynamic Maps tiles render the result, exactly as shown in this article. Because it all runs inside the EU by default, the visitor's location stays in the EEA, which keeps the locator GDPR-compliant without extra work.
Full request and response formats for every endpoint are in the MapAtlas API documentation. The Search API is also worth a look if you want the locator to discover points of interest around the visitor, not just your own branches.
A store locator is a small feature with a lot of quiet judgement inside it: understanding vague input, ranking by genuine proximity, and respecting the fact that a location is personal data. Get those three right and the "find your nearest store" box stops being an afterthought and starts being one of the most-used things on your site.
Frequently Asked Questions
What is a store locator?
A store locator is the 'find a shop near you' feature on a retail or service website. The visitor enters a postcode, city, or shares their location, and the locator returns the closest branches ranked by distance, each pinned on a map with its address, opening hours, and a route link. Under the hood it is three steps: geocode the input to a coordinate, run a nearby search against your list of locations, and render the results on a map.
How do I build a store locator?
Build a store locator in four steps. First, geocode the visitor's input (postcode or city) into a latitude and longitude with a geocoding API. Second, run a radius or nearest-neighbour query against your store coordinates to get the closest branches. Third, sort those results by distance and, optionally, by drive time. Fourth, render the ranked stores as markers on a map with popups. A maps API that offers geocoding, nearby search, and map tiles from one provider lets you do all four without stitching services together.
Do I need a store locator API?
You need geocoding, map tiles, and usually travel-time ranking; the store list itself is your own data. You can hardcode a short list of shops and compute straight-line distance yourself, but the moment you want postcode search, drive-time sorting, and a rendered map, an API that combines geocoding, matrix, and map rendering from one provider saves you from wiring three vendors together and reconciling their coordinate formats.
How does a store locator rank the nearest stores?
The simplest ranking is straight-line (great-circle) distance from the visitor's coordinate to each store, sorted ascending. That is fast and fine for dense urban networks. For a better experience, re-rank the top candidates by real travel time using a directions or matrix API, because the closest shop as the crow flies is not always the fastest to reach once rivers, motorways, and one-way systems are involved.
Is a store locator GDPR compliant?
It can be, and where the visitor is in the EU it must be. A store locator processes a location, which is personal data when tied to a user. Keep it compliant by geocoding on demand rather than storing the visitor's coordinate, using an EU-based maps API so the location never leaves the EEA, and asking for consent before reading device GPS. MapAtlas processes location queries inside the EU by default.

