Ship an address picker in 10 minutes
You'll build a checkout-style address field. Customers either type a place name and pick a suggestion, or paste their GhanaPostGPS code. Either way you get back coordinates and an AfriHex code you can save with the order.
Three calls do it all:
| Step | Call | What it gives you |
|---|---|---|
| 1. Suggest places as they type | GET /v2/search/autocomplete | Names and coordinates |
| 2. Or look up a GhanaPostGPS code | GET /v2/lookup | The code's coordinates, region and area |
| 3. Get the AfriHex code | GET /v2/hexcode | code to store and short_code to show |
You need Node.js 18 or newer and a free key from Authentication.
:::warning Keep your key on the server Anyone can read an API key in browser code. The page below talks to your own small server, and only the server talks to AfriHex. :::
1. The server (server.mjs)
import express from 'express'
const app = express()
const KEY = process.env.AFRIHEX_API_KEY
const afrihex = (path) =>
fetch(`https://api.afrihex.com${path}`, { headers: { 'X-API-Key': KEY } }).then(r => r.json())
// Suggestions as the customer types. lat/lng bias results towards the user.
app.get('/places', async (req, res) => {
const q = encodeURIComponent(req.query.q ?? '')
const near = req.query.lat ? `&lat=${req.query.lat}&lng=${req.query.lng}` : ''
const json = await afrihex(`/v2/search/autocomplete?q=${q}&limit=5${near}`)
res.json(json.data?.results ?? [])
})
// The chosen place, or a pasted GhanaPostGPS code, becomes an AfriHex code.
app.get('/pick', async (req, res) => {
let { lat, lng, gps } = req.query
let area = ''
if (gps) {
const found = await afrihex(`/v2/lookup?address=${encodeURIComponent(gps)}`)
if (!found.success) return res.status(404).json({ error: 'GhanaPostGPS code not found' })
lat = found.data.center_latitude
lng = found.data.center_longitude
area = `${found.data.area}, ${found.data.district}`
}
const hex = await afrihex(`/v2/hexcode?lat=${lat}&lng=${lng}`)
res.json({ lat: Number(lat), lng: Number(lng), area, code: hex.data.code, short_code: hex.data.short_code })
})
app.use(express.static('public'))
app.listen(3000, () => console.log('Open http://localhost:3000'))
2. The page (public/index.html)
<!doctype html>
<meta charset="utf-8">
<label>Delivery address
<input id="q" placeholder="Search a place, or paste a GhanaPostGPS code" autocomplete="off" style="width:22rem">
</label>
<ul id="list"></ul>
<p id="picked"></p>
<script>
const q = document.getElementById('q')
const list = document.getElementById('list')
const picked = document.getElementById('picked')
const isGpsCode = (s) => /^[A-Z]{2}-?\d{3,4}-?\d{4}$/i.test(s.trim())
let timer
q.addEventListener('input', () => {
clearTimeout(timer)
timer = setTimeout(async () => {
list.innerHTML = ''
if (isGpsCode(q.value)) return show(`/pick?gps=${encodeURIComponent(q.value.trim())}`)
if (q.value.trim().length < 3) return
const places = await fetch(`/places?q=${encodeURIComponent(q.value)}`).then(r => r.json())
for (const p of places) {
const li = document.createElement('li')
li.textContent = p.display_name
li.onclick = () => show(`/pick?lat=${p.latitude}&lng=${p.longitude}`, p.display_name)
list.append(li)
}
}, 250)
})
async function show(url, label = '') {
const r = await fetch(url).then(r => r.json())
list.innerHTML = ''
picked.textContent = r.error ?? `${label || r.area} · AfriHex code ${r.short_code}`
// Save r.code, r.lat and r.lng with the order.
}
</script>
3. Run it
npm init -y && npm install express
export AFRIHEX_API_KEY="your key"
node server.mjs
Open http://localhost:3000, type Spintex, pick a suggestion, and the
AfriHex code appears. Paste GA-183-8164 instead and you get Bukom, Accra.
What to save
| Field | Why |
|---|---|
code | The full AfriHex code. Store this one. |
short_code | The same code without the trailing Zs, for showing to people. Every endpoint accepts either form. |
lat, lng | The point the customer chose. |
Next steps
- Pass the customer's location as
lat/lngto/placesso nearby places come first. - Add landmark directions such as "Opposite the Shell filling station" with
GET /v2/reverse?lat=…&lng=…&descriptors=true. See Addresses. - Capture the customer's gate as well as the area: see Delivery address capture.