A "Find Stores Near Me" button looks simple: get the user's location, compare it with your stores, and show the closest results.
But once you start building it, a few questions appear. How do you request location safely? How do you calculate which store is actually closest? What happens when permission is denied? And does the same approach still work with thousands of locations?
Let's build the basic version in JavaScript and then look at what needs to change for production.
How Does "Find Stores Near Me" Work?
At its simplest, the process looks like this:
User clicks "Find Stores Near Me"
↓
Browser requests location permission
↓
Get user's latitude + longitude
↓
Compare with store coordinates
↓
Calculate + sort by distance
↓
Display nearest stores
The browser doesn't actually know which store is closest. It gives us the user's coordinates; finding the nearest location is our job.
1. Get the User's Location
Modern browsers provide the Geolocation API:
navigator.geolocation.getCurrentPosition(
(position) => {
const userLat = position.coords.latitude;
const userLng = position.coords.longitude;
console.log(userLat, userLng);
},
(error) => {
console.error("Location unavailable:", error.message);
},
{
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 60000
}
);
The browser asks the visitor for permission before returning their location. Request location when the visitor actually uses the feature, and explain why you need it rather than triggering the permission dialog immediately on page load.
Geolocation generally requires HTTPS, and users can deny permission. Your application should therefore provide another way to search, such as entering a city, ZIP/postal code, or address.
In the options above, enableHighAccuracy asks for a more precise position when available, timeout limits how long we're willing to wait, and maximumAge allows the browser to reuse a recent cached position.
For WordPress implementations, permission prompts can become part of the locator UX.
This guide covers geolocation in a WordPress store locator, including prompting visitors and triggering location detection from a custom button.
2. Prepare Your Store Coordinates
Every store needs latitude and longitude coordinates:
const stores = [
{ name: "Downtown Store", lat: 40.7128, lng: -74.0060 },
{ name: "Uptown Store", lat: 40.7831, lng: -73.9712 },
{ name: "Brooklyn Store", lat: 40.6782, lng: -73.9442 }
];
If you only have street addresses, you'll first need to convert them into coordinates using a geocoding service.
Once both the visitor and stores have coordinates, we can compare them.
3. Calculate the Nearest Store
For a basic implementation, the Haversine formula calculates the straight-line distance between two geographic coordinates.
function calculateDistance(lat1, lon1, lat2, lon2) {
const R = 6371; // Earth radius in kilometers
const dLat = (lat2 - lat1) * Math.PI / 180;
const dLon = (lon2 - lon1) * Math.PI / 180;
const a =
Math.sin(dLat / 2) ** 2 +
Math.cos(lat1 * Math.PI / 180) *
Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon / 2) ** 2;
return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
}
We can calculate each store's distance and sort the results:
const nearestStores = stores
.map(store => ({
...store,
distance: calculateDistance(
userLat, userLng, store.lat, store.lng
)
}))
.sort((a, b) => a.distance - b.distance);
nearestStores[0] is now the closest location.
Remember that Haversine gives us straight-line distance, not driving distance or travel time. Those require a routing service.
4. Put It Together: A Working "Find Stores Near Me" Button
Now let's connect the pieces.
<button id="find-nearby">Find Stores Near Me</button>
<div id="results"></div>
document.getElementById("find-nearby").addEventListener("click", () => {
navigator.geolocation.getCurrentPosition(
({ coords }) => {
const nearest = stores
.map(store => ({
...store,
distance: calculateDistance(
coords.latitude,
coords.longitude,
store.lat,
store.lng
)
}))
.sort((a, b) => a.distance - b.distance)
.slice(0, 3);
document.getElementById("results").innerHTML = nearest
.map(store =>
`<p>${store.name} — ${store.distance.toFixed(1)} km</p>`
)
.join("");
},
() => {
document.getElementById("results").textContent =
"Location unavailable. Search by city or ZIP code instead.";
},
{
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 60000
}
);
});
We now have the complete basic flow: the visitor clicks the button, grants location access, and sees the three nearest stores.
A production interface could add map markers, directions, opening hours, phone numbers, and other store information.
5. Plan for Geolocation Failure
The successful path is only half the implementation.
Visitors may deny permission, location accuracy may be poor, location services may be unavailable, or no store may exist nearby.
That's why a locator should never depend entirely on geolocation.
A simple fallback could be:
Can't access your location?
[ Enter city, ZIP code, or address ] [ Search ]
This also helps visitors who want to find stores somewhere other than their current location.
What If You Have Thousands of Stores?
Running these calculations in the browser works well for a small dataset. Sending thousands of store records to every visitor doesn't.
For larger datasets, send the user's coordinates to your backend and query only stores within a useful radius.
User coordinates
↓
Server / API
↓
Geographic radius query
↓
Nearest locations
↓
Browser
Databases with geospatial capabilities and spatial indexes can perform this filtering efficiently. Instead of sending your entire location database to the browser, your backend might return only the 10 or 20 stores relevant to that visitor.
Building It Yourself vs. Using a Store Locator
The nearest-store calculation isn't particularly complicated. The workload grows when you add maps, markers, geocoding, address search, filters, directions, mobile layouts, store management, and hundreds of locations.
For a custom application, building those components yourself may make sense.
If this is going into WordPress and you don't need custom location infrastructure, you may not need to maintain all of this yourself. A WordPress store locator plugin such as Agile Store Locator can handle nearby-location search, maps, store data, and the management interface while leaving the custom-build approach available for projects that need complete control.
The right approach depends on how much control your project needs versus how much infrastructure you want to maintain.
Final Thoughts
"Find Stores Near Me" looks like a simple button, but there's an interesting chain behind it:
permission → coordinates → distance calculation → sorting → nearest stores
The browser Geolocation API and a little JavaScript are enough for a useful prototype. For production, permission failures, search fallbacks, data quality, routing, scalability, and mobile UX all matter.
How would you implement nearest-store search in your application: client-side calculations, database geospatial queries, or a mapping/routing service?
Top comments (0)