The Map component renders an interactive map using MapLibre GL JS. Vector layers can be added via the vectorLayers prop or shorthand props like geojson, csv, directus, etc. Layers can include searchable fields for advanced filtering.
Live Examples
Simple map with base layers
The most basic Map configuration. Displays a map centered on coordinates 37,37 (Turkey) at zoom 8 with two switchable basemap layers.
Available basemap shorthand values: CAWM, OSM, EsriSatellite, EsriStreets, EsriTopo, GoogleSatellite, GoogleRoadmap, GoogleTerrain, GoogleAlteredRoadmap, CartoDB, StamenTerrain, OSMMapnick, OSMCycle.
<Map client:only="react" height="500px" center="37,37,8" baseLayers={['EsriSatellite', 'GoogleTerrain']}/>Custom basemap configuration
Instead of shorthand keys, provide full configuration objects with name, url, and optional attribution:
<Map client:only="react" height="500px" center="37,37,8" baseLayers={[ { name: "Esri Topo", url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}", }, 'GoogleSatellite' ]}/>Adding map controls
Add navigation, scale, fullscreen, and layer-switcher controls using their respective props. Each accepts a position string (top-right, top-left, bottom-right, bottom-left).
<Map client:only="react" height="500px" center="37,37,8" navigationControl="top-left" scaleControl="bottom-left" fullscreenControl="top-right" layerControl="top-right" baseLayers={['EsriSatellite', 'GoogleTerrain']}/>Load geo-data from a GeoJSON file
Use the geojson shorthand prop to load a GeoJSON file directly. fitToContent: true automatically zooms the map to show all features.
<Map client:only="react" height="500px" geojson={{ name: "Kahramanmaraş Survey Sites", path: "/data/ksa.geojson", popup: "<b>${Site_Name}</b><br/>${Description}", fitToContent: true, style: { type: 'circle', paint: { 'circle-radius': 4, 'circle-color': '#ff6b6b', 'circle-stroke-width': 1, 'circle-stroke-color': '#ffffff' } } }} baseLayers={['EsriSatellite', 'GoogleTerrain']}/>Load geo-data from a CSV file
Load point data from a CSV file. Use lng and lat to specify which columns contain the coordinates.
<Map client:only="react" height="500px" center="37,37,8" csv={{ path: "/data/ksa.csv", lng: "Longitude", lat: "Latitude", popup: "<b>${Site_Name}</b><br/>${Description}", style: { type: 'circle', paint: { 'circle-radius': 8, 'circle-color': '#4ecdc4', 'circle-stroke-width': 2, 'circle-stroke-color': '#ffffff' } } }} baseLayers={['EsriSatellite', 'GoogleTerrain']}/>Client-side filtering with GeoJSON
Filter features client-side using a Directus-like filter object. Supported operators: _eq, _neq, _in, _nin, _contains, _ncontains, _gt, _gte, _lt, _lte, _null, _nnull. Multiple conditions use AND logic.
<Map client:only="react" height="500px" geojson={{ path: "/data/ksa.geojson", name: "Middle Bronze Age Sites", filter: { Middle_Bronze: { _eq: "true" } }, popup: "<b>${Site_Name}</b><br/>${Description}", fitToContent: true, style: { type: 'circle', paint: { 'circle-radius': 6, 'circle-color': '#e74c3c', 'circle-stroke-width': 1, 'circle-stroke-color': '#ffffff' } } }} baseLayers={['EsriSatellite', 'GoogleTerrain']}/>Multiple Vector Layers
Add multiple vector layers (GeoJSON and CSV) with independent styles and popups using the vectorLayers prop:
<Map client:only="react" height="600px" scaleControl="bottom-left" vectorLayers={[ { name: 'GeoJSON Sites', source: { type: 'geojson', url: '/data/ksa.geojson' }, popupTemplate: '<b>${Site_Name}</b><br/>${Description}', fitToContent: true, style: { type: 'circle', paint: { 'circle-radius': 8, 'circle-color': '#ff6b6b' } } }, { name: 'CSV Sites', source: { type: 'csv', url: '/data/ksa.csv' }, popupTemplate: '<b>${Site_Name}</b>', style: { type: 'circle', paint: { 'circle-radius': 4, 'circle-color': '#4ecdc4' } } } ]} baseLayers={['EsriSatellite', 'GoogleTerrain']}/>Load map from MapLibre style JSON
Load a complete map configuration from a MapLibre style JSON file. The style file can include sources, layers, and full styling:
<Map client:only="react" height="500px" center="37,37,8" mapStyle="/data/ksa.json"/>Override and expand style JSON layers
Use styleOverrides to override paint/layout properties or add extra features (popupTemplate, fitToContent) to layers defined in a MapLibre style JSON:
<Map client:only="react" height="500px" mapStyle="/data/ksa.json" styleOverrides={{ 'ksa': { paint: { 'circle-color': '#00ff00', 'circle-radius': 8 }, popupTemplate: '<b>${Site_Name}</b>', fitToContent: true } }}/>Load data from Directus
Load geographical data directly from a Directus collection. geoField specifies which field contains GeoJSON geometry. Filter with Directus query syntax via queryString.
Credentials can be passed directly or via PUBLIC_DIRECTUS_URL / PUBLIC_DIRECTUS_TOKEN env vars.
<Map client:only="react" height="500px" center="37,37,8" directus={{ table: "scms_ksa", geoField: "geometry", queryString: "filter[Hellenistic_Roman][_eq]=true", name: "Hellenistic-Roman Sites", popup: "<b>${Site_Name}</b><br/>${Description}", fitToContent: true, style: { type: 'circle', paint: { 'circle-radius': 6, 'circle-color': '#9b59b6' } } }} baseLayers={['EsriSatellite', 'GoogleTerrain']}/>Vector Layer Search
Vector Layers with Search
Enable per-layer search by setting searchInFields on a vector layer. A search icon appears in the layer control; clicking it opens a search interface supporting both simple free-text and advanced field/operator/value queries.
<Map client:only="react" height="600px" vectorLayers={[ { name: 'Archaeological Sites', source: { type: 'geojson', url: '/data/ksa.geojson' }, popupTemplate: '<b>${Site_Name}</b><br/>${Item_Label}', searchInFields: { Site_Name: "Site Name", Item_Label: "Item Label", Site_Description: "Description" }, fitToContent: true, style: { type: 'circle', paint: { 'circle-radius': 6, 'circle-color': '#ff6b6b' } } } ]} baseLayers={['EsriSatellite', 'OSM']}/>Props API
MapProps
| Prop | Type | Default | Description |
|---|---|---|---|
height | string | '400px' | Map height (CSS value) |
center | string | — | Initial center as "lng,lat,zoom" |
baseLayers | BaseLayerConfig[] | BasemapKey[] | — | Base layers (use shorthand keys or full config objects) |
vectorLayers | VectorLayerConfig[] | — | Vector data layers |
geojson | shorthand | — | Shorthand for a single GeoJSON layer |
csv | shorthand | — | Shorthand for a single CSV layer |
directus | shorthand | — | Shorthand for a single Directus layer |
mapStyle | string | object | — | MapLibre style JSON URL or object |
styleOverrides | Record<string, LayerOverride> | — | Override/extend layers from mapStyle |
navigationControl | ControlPosition | — | Navigation control position |
scaleControl | ControlPosition | — | Scale bar position |
fullscreenControl | ControlPosition | — | Fullscreen button position |
layerControl | boolean | ControlPosition | true | Layer switcher position |
geolocateControl | ControlPosition | — | Geolocate button position |
sprite | string | — | MapLibre sprite URL |
ControlPosition: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'
VectorLayerConfig
| Prop | Type | Description |
|---|---|---|
name | string | Layer display name |
source | SourceConfig | Data source (geojson, csv, directus, api…) |
style | object | MapLibre paint/layout properties |
popupTemplate | string | HTML popup with ${fieldName} placeholders |
visible | boolean | Initial visibility (default: true) |
fitToContent | boolean | Auto-zoom to layer bounds |
filter | FilterObject | function | Client-side feature filter |
searchInFields | SearchInFields | Fields to expose in the search UI |
DirectusShorthand (for Map)
interface DirectusShorthand { table: string; geoField?: string; // Field containing GeoJSON geometry queryString?: string; // Directus filter query string name?: string; // Layer display name popup?: string; // Popup HTML template fitToContent?: boolean; style?: object; url?: string; // defaults to PUBLIC_DIRECTUS_URL token?: string; // defaults to PUBLIC_DIRECTUS_TOKEN}