Build a Store Locator for Vietnam with MapLibre and a Geocoding API
A practical Next.js tutorial for building a Vietnam store locator: address search, place resolution, nearest-branch ranking, and MapLibre markers without exposing your API key.
A store locator looks simple: show branches on a map and help users find the nearest one. In production, however, the feature has to connect three different problems:
- Convert a Vietnamese address into reliable coordinates.
- Rank branches by distance from the selected location.
- Render the result without exposing a private API key in browser code.
This guide builds that flow with Next.js, MapLibre GL JS, and the
GoGoDuk /v1/suggest and
/v1/place/resolve endpoints.
Architecture
Keep map rendering, address intelligence, and branch data separate:
The browser calls your own backend routes. The backend adds
X-API-Key, so the key never appears in client JavaScript or the network
requests sent directly to a third-party domain.
Model your branches
Geocode branch addresses when they are created or updated, not on every customer search. Store coordinates as numbers and keep the original address for display:
For a large network, store this data in PostgreSQL/PostGIS and query nearby branches with a spatial index. For tens or hundreds of branches, ranking a small in-memory result set is often enough.
Proxy address suggestions through Next.js
Create app/api/locations/suggest/route.ts:
Store the key in a server-only environment variable:
Do not prefix the key with NEXT_PUBLIC_. That prefix deliberately exposes a
value to browser bundles.
Resolve the selected place
Autocomplete results contain a stable placeId. After the user chooses an
item, resolve that ID into coordinates through another server route:
Only resolve a place after selection. Calling place resolution for every keystroke adds latency and consumes quota without improving the dropdown.
Rank the nearest branches
For straight-line proximity, use the Haversine formula:
Haversine is useful for shortlist ranking, but it is not driving distance. A river, bridge, one-way street, or mountain can make the nearest branch by straight line slower to reach. Label the value as "approximately X km away", and use a routing or distance-matrix service when travel time affects the business decision.
Render the result with MapLibre
Install MapLibre:
The map receives only coordinates and display data:
MapLibre is the renderer; it does not provide address search by itself. Your style can come from your own tile server or another compatible provider while GoGoDuk handles Vietnamese address search and place resolution. Unlike the GoGoDuk API key, a browser-facing map style URL is expected to be public.
Production checklist
- Debounce autocomplete by 200-300 ms.
- Cancel stale requests when the input changes quickly.
- Require users to select a suggestion instead of trusting free-form text.
- Keep the GoGoDuk key in a server-only environment variable.
- Cache stable branch data and pre-geocode branch addresses.
- Show district/city context for branches with similar names.
- Treat Haversine distance as an estimate, not route duration.
- Return a list view alongside the map for accessibility and mobile users.
Where this differs from delivery zones
A store locator ranks discrete branch points. A delivery-zone system answers whether a customer lies inside a service polygon and may apply a fee for that area. If your next step is shipping coverage, read How to build delivery zones in Vietnam.
For more detail on autocomplete UX and address validation, see Vietnam Address Autocomplete API.
Start building
Create a free API key, test a real customer address through
/v1/suggest, resolve the selected placeId, and
rank it against a small branch dataset. That is enough to ship the first useful
version of a Vietnam store locator without coupling address search to your map
renderer.
Want to use GoGoDuk?
Free forever — 100 requests/day per account, no credit card. Higher limits on request.
Sign up →