Build a store locator
Build a store locator
A classic integration: let users search for places, list results with thumbnails and open/closed status, and show full details when they pick one. Uses Search, Places, and a map.
Scopes required: search, places (and tiles for the map).
1. Search as the user types
Call GET /search with the query. Debounce input to stay within rate limits.
async function search(q) {
const res = await fetch(
"https://navvo.io/api/v1/search?" + new URLSearchParams({ q, limit: "10" }),
{ headers: { "x-api-key": KEY } }
);
const data = await res.json();
return data.places.items; // [{ slug, nameEn, categories, rating, center, sponsored }]
}
2. Render results with thumbnails & status
For each result, fetch a lightweight thumbnail and open/closed state from GET /places/thumb:
async function thumb(slug) {
const res = await fetch(
"https://navvo.io/api/v1/places/thumb?" + new URLSearchParams({ slug }),
{ headers: { "x-api-key": KEY } }
);
return res.json(); // { url, source, rating, openState, openText }
}
Parse the WKT center to plot each result on the map:
function parsePoint(wkt) {
// "POINT(35.8806 31.9461)" -> [lng, lat]
const [lng, lat] = wkt.replace(/^POINT\(|\)$/g, "").split(" ").map(Number);
return [lng, lat];
}
3. Show full detail on selection
When the user picks a result, load the full record from GET /places/{slug}:
async function detail(slug) {
const res = await fetch(`https://navvo.io/api/v1/places/${encodeURIComponent(slug)}`, {
headers: { "x-api-key": KEY },
});
const place = await res.json();
if (!place) return null; // unknown slug returns 200 with null body
return place; // includes reviews, photos, questions, arrivalIntelligence
}
Display nameEn/nameAr, categories, contact, openingHours, rating, photos, and reviews.
4. Send users to the right door
place.arrivalIntelligence gives you the recommended entrance — better than the center pin for directions:
const target = place.arrivalIntelligence?.candidates?.[0]?.routeTarget; // { lat, lng }
const directionsUrl =
`https://navvo.io/api/v1/routing/route`; // POST with that target — see Directions guide
arrivalIntelligence.candidates[0].routeTarget (the recommended entrance) as the routing destination instead of center. For a delivery app, also show lastMetersGuidance to the driver.Putting it together
Search
GET /search?q=… → list of { slug, center, … }.
Enrich
GET /places/thumb?slug=… for each → thumbnail + open status.
Detail
GET /places/{slug} on selection → full record + arrival entrance.
Route
POST /routing/route (or /traffic/route) to the recommended entrance.