Skip to Content
ExamplesComplete Example

Complete SDK Example

Complete SDK integration showing map with places loaded

Complete SDK flow demo: init, markers, focus, route

This example shows a realistic integration path using a class-based pattern that encapsulates the SDK, map, and place state. This is one of many valid approaches — the same flow works equally well with plain functions, React hooks, or framework-specific state management. It combines:

  • SDK initialization
  • map creation
  • place loading
  • marker creation
  • polygon styling
  • route creation
  • map fitting

End-to-end example

import { TextPosition, initializeSDK, loadStyles, type MapVXMap, type MapVXSDK, type MVXPlace, } from "@mapvx/web-js" loadStyles() class MapExperience { private readonly sdk: MapVXSDK private map?: MapVXMap private places: MVXPlace[] = [] constructor(private readonly apiKey: string) { this.sdk = initializeSDK(apiKey, { lang: "es", cache: { persistent: true, }, }) } async init(container: HTMLElement, parentPlaceId?: string): Promise<void> { const center = await this.resolveInitialCenter(parentPlaceId) this.map = this.sdk.createMap(container, { center, zoom: parentPlaceId ? 18 : 16, parentPlaceId, onMapReady: () => { console.log("Map ready") }, onFloorChange: (floorId) => { console.log("Floor changed", floorId) }, }) await this.loadPlaces(parentPlaceId) this.renderInitialMarkers() } private async resolveInitialCenter(parentPlaceId?: string) { if (parentPlaceId) { const parentPlace = await this.sdk.getPlaceDetail(parentPlaceId) return parentPlace.position } const places = await this.sdk.getAvailablePlaces() return places[0]?.position ?? { lat: 4.666918, lng: -74.053065 } } private async loadPlaces(parentPlaceId?: string): Promise<void> { this.places = parentPlaceId ? await this.sdk.getSubPlaces(parentPlaceId) : await this.sdk.getAvailablePlaces() } private renderInitialMarkers(): void { if (!this.map) return this.places.slice(0, 3).forEach((place) => { this.map!.addMarker({ id: `marker-${place.mapvxId}`, coordinate: place.position, floorId: place.inFloors?.[0], text: place.title, textPosition: TextPosition.bottom, icon: "/assets/icons/marker-info.svg", iconProperties: { width: 36, height: 36, }, anchor: "bottom", }) }) } async focusPlace(placeId: string): Promise<void> { if (!this.map) return const place = await this.sdk.getPlaceDetail(placeId) this.map.setPlacesAsSelected([place.mapvxId], "#0F766E") this.map.addBorderToPlaces([place.mapvxId], "#134E4A", 2) this.map.fitCoordinates([place.position], { maxZoom: 19, }) } async routeBetween(originId: string, destinationId: string): Promise<void> { if (!this.map) return const route = await this.map.addRoute({ initialLocation: { id: originId }, finalLocation: { id: destinationId }, preferAccessibleRoute: false, }) const parentPlaceId = this.places.find((place) => place.mapvxId === destinationId)?.parentId if (parentPlaceId) { this.map.fitRouteByPlace(route, parentPlaceId, { padding: { top: 80, right: 40, bottom: 120, left: 40, }, }) } } destroy(): void { this.map?.removeAllMarkers() this.map?.removeAllRoutes() this.map?.destroyMap() } } const experience = new MapExperience("<YOUR_API_KEY>") experience.init(document.getElementById("map") as HTMLElement, "<OPTIONAL_PARENT_PLACE_ID>")

What this example intentionally leaves out

Last updated on