Skip to main content

Add Custom Search data to Search Box (Web)

This example demonstrates how to pass custom data into a <mapbox-search-box> HTML custom element so that search results include both custom search results and Mapbox provided results. To do this, you must leverage the componentOptions.customSearch parameter.

The example below contains an array of formatted features data called airports which represent small airfields in the Northeast United States. This data can come from any source like an external API or local data, but it must be formatted as a suggestion result as returned by the Search Box API. Also, each suggestion needs to contain a _geometry object that includes coordinates and type properties as specified in the retrieved Feature format. This allows our custom data to work interchangeably when it is returned inside SearchBox.

The customSearch parameter receives the search query from SearchBox and we pass this to the async searchAirports() function that returns a Promise which resolves to our custom search data suggestions.

Search for '44N', 'Sky Acres' or 'IZG' to see the custom airport data being returned within the Search Box results. If your application included a map, you could then click on a custom data result and handle that on the map as you'd like.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Add Custom Search data to Search Box (Web)</title>
</head>

<body>
<!-- Load Mapbox GL JS -->
<link href="https://api.mapbox.com/mapbox-gl-js/v3.17.0/mapbox-gl.css" rel="stylesheet"/>
<script src="https://api.mapbox.com/mapbox-gl-js/v3.17.0/mapbox-gl.js"></script>

<div id="map" style="position: absolute; width: 100%; height: 100%">
<div
id="search-box"
style="position: absolute; top: 0; right: 0; margin: 20px; z-index: 20; width: 300px;">
</div>
</div>

<script>

// TO MAKE THE MAP APPEAR YOU MUST
// ADD YOUR ACCESS TOKEN FROM
// https://account.mapbox.com
const ACCESS_TOKEN = 'YOUR_MAPBOX_ACCESS_TOKEN';
const script = document.getElementById('search-js');
const center = [-70.25463, 43.66097] // starting position [lng, lat] of Portland, ME

// wait for the Mapbox Search JS script to load before using it
script.onload = function () {

mapboxgl.accessToken = ACCESS_TOKEN;

const map = new mapboxgl.Map({
container: 'map',
center: center,
zoom: 8.8
});

const airports = [
// This data has been formatted to match the format specified in the customSearch documentation
// http://docs.mapbox.com/mapbox-search-js/api/web/search/#mapboxsearchboxcomponentoptions-properties-customsearch
{
"name": "4AK7 - Aleknagik Mission Strip",
"place_formatted": "ALEKNAGIK, AK",
"mapbox_id": "airport_4AK7",
"feature_type": "airport",
"_geometry": {
"type": "Point",
"coordinates": [
-158.597221680699,
59.2809237361098
]
}
},
{
"name": "44N - Sky Acres",
"place_formatted": "MILLBROOK, NY",
"mapbox_id": "airport_44N",
"feature_type": "airport",
"_geometry": {
"type": "Point",
"coordinates": [
-73.7380239239491,
41.7074323474509
]
}
},
{
"name": "3B1 - Greenville Muni",
"place_formatted": "GREENVILLE, ME",
"mapbox_id": "airport_3B1",
"feature_type": "airport",
"_geometry": {
"type": "Point",
"coordinates": [
-69.5516497188597,
45.4628406764533
]
}
},
{
"name": "IZG - Eastern Slopes Rgnl",
"place_formatted": "FRYEBURG, ME",
"mapbox_id": "airport_IZG",
"feature_type": "airport",
"_geometry": {
"type": "Point",
"coordinates": [
-70.9478895415445,
43.9911478692315
]
}
},
{
"name": "BHB - Hancock County/Bar Harbor",
"place_formatted": "BAR HARBOR, ME",
"mapbox_id": "airport_BHB",
"feature_type": "airport",
"_geometry": {
"type": "Point",
"coordinates": [
-68.3614895334381,
44.4497144207149
]
}
},
{
"name": "EEN - Dillant/Hopkins",
"place_formatted": "KEENE, NH",
"mapbox_id": "airport_EEN",
"feature_type": "airport",
"_geometry": {
"type": "Point",
"coordinates": [
-72.2707787994177,
42.8983976236563
]
}
},
{
"name": "PVC - Provincetown Muni",
"place_formatted": "PROVINCETOWN, MA",
"mapbox_id": "airport_PVC",
"feature_type": "airport",
"_geometry": {
"type": "Point",
"coordinates": [
-70.2207225212066,
42.0722864225276
]
}
},
{
"name": "4B0 - South Albany",
"place_formatted": "SOUTH BETHLEHEM, NY",
"mapbox_id": "airport_4B0",
"feature_type": "airport",
"_geometry": {
"type": "Point",
"coordinates": [
-73.8339459545136,
42.5607308383581
]
}
},
{
"name": "1C3 - Argyle",
"place_formatted": "ARGYLE, NY",
"mapbox_id": "airport_1C3",
"feature_type": "airport",
"_geometry": {
"type": "Point",
"coordinates": [
-73.4701958825037,
43.2545365362011
]
}
}
]

const searchAirports = async(query) => {
// lowerCase() both the query and the airport name to ensure consistent matching
const q = query.toLowerCase().trim()
const matches = airports.filter(a => a.name.toLowerCase().includes(q))
return matches
}

// instantiate a <mapbox-search-box> element using the MapboxSearchBox class
const searchBox = new mapboxsearch.MapboxSearchBox()

// pass searchbox your access token for use in requests
searchBox.accessToken = ACCESS_TOKEN;

// set the mapboxgl library to use for markers and enable the marker functionality
searchBox.mapboxgl = mapboxgl
searchBox.marker = true

// set the componentOptions customSearch parameter
searchBox.componentOptions = {
customSearch: (query) => searchAirports(query)
}

// bind the search box instance to the map instance
searchBox.bindMap(map)

// add the search box instance to the DOM
document.getElementById('search-box').appendChild(searchBox)
}
</script>
</body>
</html>
Was this example helpful?