Add Mapbox Geocoding Search to a Web Map Without Exposing Your Token
Add a debounced Mapbox Geocoding search to a web map, keep the access token secure, parse GeoJSON features, and handle rate limits with clear verification steps.
16 Aug 2026, 18:14 UTC

Desired outcome
You want a search box that geocodes user input with Mapbox Geocoding and moves a Mapbox GL JS map to the result, while avoiding token exposure and rate-limit errors. The useful takeaway is to keep the access token off the client when possible, debounce input, and treat the first feature as a suggestion not a guarantee.
Prerequisites
A Mapbox account with an access token that has Geocoding scope. A web page that loads Mapbox GL JS for rendering. If you call the Geocoding API directly from the browser, you accept that the token is visible in network requests. For production, plan a minimal server proxy that injects the token server-side.
Environment variables for the token on the server side, e.g. MAPBOX_TOKEN. No special permissions are needed in the browser beyond network access. CORS is enabled by Mapbox for the Geocoding endpoint, but an invalid or missing token returns 401 which browsers may mask.
Implementation
Token handling and request shape
Do not hard-code the token in public JavaScript. If a proxy is used, the client calls your own endpoint and the server appends the token to the Mapbox URL. The Geocoding endpoint returns GeoJSON. The features array holds coordinate pairs in [longitude, latitude] order, EPSG:4326.
Build the request URL with placeholders for query and optional filters. Example client call via your proxy:
// run in browser, requires fetch support
const query = encodeURIComponent(inputValue);
const url = `/api/geocode?q=${query}&types=place,address`;
fetch(url).then(r => r.json()).then(handle)
The server side then forwards to Mapbox Geocoding with the token in the Authorization header or as a query parameter, and returns the JSON to the client.
Debounce user input
Rapid typing triggers many requests and can hit the default limit of 600 requests per minute. Implement a debounce of about 300 ms to wait for typing to pause before sending.
let timer;
function onInput(e){
clearTimeout(timer);
timer = setTimeout(() => doGeocode(e.target.value), 300);
}
This reduces unnecessary calls and lowers the chance of HTTP 429 responses.
Parse and move the map
When the response arrives, check for a features array. If present, use the first feature’s center to place a marker or fly the map. Filtering by place_type or context can improve relevance because the first feature is ordered by relevance, not by exact match.
function handle(data){
const feature = data.features && data.features[0];
if(!feature) return;
const [lon, lat] = feature.center;
map.flyTo({center:[lon, lat], zoom:14});
// create or update marker at [lon, lat]
}
Note the coordinate order is longitude first. Using latitude first will place the marker incorrectly.
Verification checks
In the browser console confirm the request URL is formed correctly and the response JSON contains a features array. In the Network tab verify the request is GET, returns status 200, and content-type is application/json.
After selecting a suggestion, verify the map flies to the returned coordinates and a marker appears at the expected position. Inspect response headers for X-RateLimit-Limit and Remaining to adjust request frequency proactively.
Simulate a network drop, then restore connectivity, and confirm retry logic surfaces a user-friendly message and succeeds after the error clears. Trigger rapid typing in a test environment to ensure debounce prevents a burst of requests and error handling shows a retry option on 429.
Recovery options and limitations
Handle HTTP 4xx/5xx errors by showing a non-technical message with a retry button. For 429, back off and retry after a short delay. For 401, treat as configuration error and do not retry automatically.
Limitations: exposing the token client-side can lead to unintended usage and quota exhaustion. Results may be ambiguous; consider showing a suggestion list instead of auto-flying to the first feature. Coordinates are lon/lat; if your downstream system expects lat/lon, transform explicitly. Rate limits are per token and per account; monitor usage in the Mapbox dashboard.
Rollback is not required for read-only geocoding. If you added a proxy, you can revert to direct calls for local testing by removing the proxy route, accepting the token visibility risk.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.