Embed a MapLibre Map + Vietnam Address Search in Plain JavaScript
Embed a MapLibre map and a Vietnam address autocomplete with plain HTML/JavaScript — no framework, using GoGoDuk's /v1/suggest, and drop a pin from the coordinates.
Not every project needs React. A landing page, a contact page, or a booking form often just needs a map and an address box — and plain HTML plus JavaScript is enough, without dragging in a whole framework.
This post does exactly that: embed a MapLibre GL JS map and a Vietnam address
autocomplete using two public GoGoDuk endpoints —
/v1/suggest for predictions and
/v1/place/resolve for coordinates — then drop a
pin on the map. The whole thing fits in one HTML file plus a tiny backend proxy.
Why plain JavaScript
If you already run a React/Next.js app, use the React autocomplete component — it's cleaner for complex forms. But for a static page, adding React just to get one input is overkill: bigger bundle, heavier build, harder for a newcomer to edit.
Plain JavaScript fits when:
- The page is small and low-interaction — a landing page, a "Contact" or "Stores" page.
- You're embedding a map into an existing site (WordPress, static HTML) without changing the whole stack.
- You want to understand each moving part before wrapping it in a component.
Embed a basic MapLibre map
MapLibre GL JS is an open-source vector map renderer (a fork of Mapbox GL JS, free). Load it from a CDN and create a map pointing at your style:
Note MapLibre takes coordinates as [lon, lat] (longitude first), the opposite
of the usual "lat, lon" habit — this is the single most common beginner mistake.
Why you need a backend proxy
The big temptation is to call api.gogoduk.com straight from browser JavaScript.
Don't. That puts your X-API-Key in plain sight in the Network tab and the
page source — anyone can copy it and burn your quota.
The right way: the browser calls a backend route of your own, and that route
attaches X-API-Key before forwarding to GoGoDuk. The key never leaves the server.
Here's a plain Node example (no framework), but the principle is identical in PHP,
Python, or any backend:
The browser only ever sees /api/suggest and /api/resolve — never the key.
Add the search box + call /v1/suggest (with debounce)
/v1/suggest takes input (minimum 2 characters) and returns a list of
predictions, each with placeId, mainText (the primary line) and
secondaryText (the admin hierarchy). Don't fire a request per keystroke —
debounce it so fast typing collapses into one request, lighter and cheaper on
quota:
Select a result → resolve coordinates → drop a pin
Autocomplete only returns a placeId (a stable identifier), not coordinates. When
the user clicks a suggestion, call /v1/place/resolve to get result.lat and
result.lon, then place a marker and flyTo it:
Try typing "201 Trần Não" and picking the first suggestion — the map flies to
10.7866, 106.7298 and pins exactly at that address. The whole flow —
type → /v1/suggest → select → /v1/place/resolve → marker — fits in one HTML
file and a ten-line proxy.
A few production notes
- Never put
X-API-Keyin the client. Always go through a backend proxy as above. - Debounce the input (200–400ms) so you don't spam requests or flicker results.
- Coordinate order: MapLibre and GoGoDuk both use
[lon, lat]; the resolve field is namedlon(notlng). Get the order wrong and your pin lands in the sea. - Map style:
demotiles.maplibre.orgis only for testing. In production use a stable style/tile source (self-hosted or a tile provider) so the Vietnam map is crisp and detailed enough.
When to move to a framework
Plain JavaScript is fine for one search box and a map. But once the form gets complex — many fields, validation, keyboard navigation in the dropdown, binding to your checkout state — a structured component is easier to maintain. At that point move to the React/Next.js autocomplete component, or read the Vietnam Address Autocomplete API overview for the UX design behind it. Want a full nearest-branch finder? There's a ready guide on building a Store Locator with MapLibre.
/v1/suggest and /v1/place/resolve are in GoGoDuk's free tier: 100 requests/day
per account, no credit card — enough for prototypes and many real small sites.
Create an account, grab an API key, and embed your first
map this afternoon. Questions or want to show off what you built? Join our
Telegram support group.
Want to use GoGoDuk?
Free forever — 100 requests/day per account, no credit card. Higher limits on request.
Sign up →