Place Interaction and Styling
In this example, we’ll cover how to search for places using the SDK, how to highlight and style them on the map, and how to respond to user clicks on map places.
Setup
Initialize the SDK and create a map before using any place or interaction APIs.
import { initializeSDK } from "@mapvx/web-js"
const sdk = initializeSDK("<YOUR-API-KEY>")
const map = await sdk.createMap(document.getElementById("map"), {
center: { lat: -33.417733, lng: -70.606573 },
zoom: 17,
})Fetching institutions
An Institution is a conglomerate of places — a building,
campus, or other organizational unit. Use getInstitutions to retrieve all institutions available
to your API key.
const institutions = await sdk.getInstitutions()
institutions.forEach((institution) => {
console.log(institution.mapvxId, institution.title)
})This is useful when you need to scope a place search to a specific institution. Store the mapvxId
of the institution you want to work with for use in the steps below.
Searching places by text input
Use getPlacesByInput to search for places matching a text query within an institution. The
function returns an array of MVXPlace objects.
const results = await sdk.getPlacesByInput(
"coffee", // search text
"<INSTITUTION_ID>" // required: institution to search within
)
results.forEach((place) => {
console.log(place.mapvxId, place.title)
})Narrowing the search scope
You can restrict the search to a specific parent place (for example, a single building within a
campus) by providing the optional parentPlaceId argument.
const results = await sdk.getPlacesByInput(
"pharmacy",
"<INSTITUTION_ID>",
"<PARENT_PLACE_ID>" // optional: limit to this building or area
)Additional optional arguments allow you to pass proximity information so that results closer to a given coordinate or floor are ranked higher:
const results = await sdk.getPlacesByInput(
"restroom",
"<INSTITUTION_ID>",
"<PARENT_PLACE_ID>",
[], // otherParentPlacesIds
"search", // origin label (arbitrary string, used for analytics)
"-33.417733", // lat (as string)
"-70.606573", // lng (as string)
"<FLOOR_ID>" // floor
)Getting details for a specific place
If you already know the MapVX ID of a place, use getPlaceDetail to fetch its full data as an
MVXPlace.
const place = await sdk.getPlaceDetail("<PLACE_ID>")
console.log(place.title)
console.log(place.description)
console.log(place.position) // { lat, lng }The mapvxId on the returned object is what the map styling methods require. If you only have a
client-side identifier (clientId), resolve it to a mapvxId through this call before passing it
to any map method.
Highlighting places on the map
Coloring places
Use setPlacesAsSelected to fill one or more place
polygons with a highlight color. Pass an array of MapVX IDs and an optional hex color string.
// Highlight a single place with the default selection color
map.setPlacesAsSelected(["<PLACE_ID>"])
// Highlight multiple places with a custom color
map.setPlacesAsSelected(["<PLACE_ID_A>", "<PLACE_ID_B>", "<PLACE_ID_C>"], "#0076B6")Every call to setPlacesAsSelected replaces the previous selection. If you pass an empty array, all
highlights are removed. The color argument changes the base color for all future calls, so use it
deliberately.
To remove all colored places without making a new selection, call
clearColoredPlaces:
map.clearColoredPlaces()Adding borders to places
Use addBorderToPlaces to outline place polygons with a
colored border. Both color and width must be provided together when overriding the style
defaults.
// Add a border using the style's default color and width
map.addBorderToPlaces(["<PLACE_ID>"])
// Add a border with a custom color and width (both required together)
map.addBorderToPlaces(["<PLACE_ID_A>", "<PLACE_ID_B>"], "#E53935", 3)As with coloring, the color and width arguments become the base style for subsequent calls.
Remove all borders with clearBorderedPlaces:
map.clearBorderedPlaces()Combining fills and borders
You can apply both a fill color and a border to the same set of places simultaneously:
const placeIds = ["<PLACE_ID_A>", "<PLACE_ID_B>"]
map.setPlacesAsSelected(placeIds, "#0076B6")
map.addBorderToPlaces(placeIds, "#004A8F", 2)Listening to place clicks
Starting the click listener
Register a callback with startClickListener to receive the
MapVX ID of any place the user clicks on the map.
map.startClickListener((placeId: string) => {
console.log("Clicked place:", placeId)
})A common pattern is to fetch full place details on click and then highlight the selected place:
map.startClickListener(async (placeId: string) => {
// Fetch details for the clicked place
const place = await sdk.getPlaceDetail(placeId)
console.log("Selected:", place.title, place.description)
// Highlight the clicked place on the map
map.setPlacesAsSelected([placeId], "#0076B6")
})Stopping the click listener
Call stopClickListener when interaction is no longer
needed, for example when navigating away from a search view.
map.stopClickListener()Checking if a point is inside the map bounds
Use isInsideBounds to verify whether a coordinate falls within
the map’s configured maximum bounds. This returns true if no maximum bounds have been set.
const userPosition = { lat: -33.417733, lng: -70.606573 }
if (map.isInsideBounds(userPosition)) {
console.log("User is within the mapped area")
} else {
console.log("User is outside the mapped area")
}This is useful when deciding whether to show routing or place interaction UI based on the user’s current GPS position.
Putting it all together
The following example combines all the pieces above into a self-contained search and highlight flow.
import { initializeSDK } from "@mapvx/web-js"
const sdk = initializeSDK("<YOUR-API-KEY>")
const map = await sdk.createMap(document.getElementById("map"), {
center: { lat: -33.417733, lng: -70.606573 },
zoom: 17,
})
// 1. Retrieve institutions and pick the one to search within
const institutions = await sdk.getInstitutions()
const institution = institutions[0]
// 2. Search places by user input
async function searchAndHighlight(query: string): Promise<void> {
const results = await sdk.getPlacesByInput(query, institution.mapvxId)
if (results.length === 0) {
map.clearColoredPlaces()
map.clearBorderedPlaces()
return
}
const ids = results.map((place) => place.mapvxId)
// Highlight all results with a fill and a border
map.setPlacesAsSelected(ids, "#0076B6")
map.addBorderToPlaces(ids, "#004A8F", 2)
}
// 3. Let the user click individual places for details
map.startClickListener(async (placeId: string) => {
const place = await sdk.getPlaceDetail(placeId)
console.log("Name:", place.title)
console.log("Description:", place.description)
// Narrow the highlight to just the clicked place
map.setPlacesAsSelected([placeId], "#E53935")
})
// 4. Trigger a search (e.g., from a search input field)
const searchInput = document.getElementById("search") as HTMLInputElement
searchInput.addEventListener("input", () => {
searchAndHighlight(searchInput.value)
})