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']}
/>

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

PropTypeDefaultDescription
heightstring'400px'Map height (CSS value)
centerstringInitial center as "lng,lat,zoom"
baseLayersBaseLayerConfig[] | BasemapKey[]Base layers (use shorthand keys or full config objects)
vectorLayersVectorLayerConfig[]Vector data layers
geojsonshorthandShorthand for a single GeoJSON layer
csvshorthandShorthand for a single CSV layer
directusshorthandShorthand for a single Directus layer
mapStylestring | objectMapLibre style JSON URL or object
styleOverridesRecord<string, LayerOverride>Override/extend layers from mapStyle
navigationControlControlPositionNavigation control position
scaleControlControlPositionScale bar position
fullscreenControlControlPositionFullscreen button position
layerControlboolean | ControlPositiontrueLayer switcher position
geolocateControlControlPositionGeolocate button position
spritestringMapLibre sprite URL

ControlPosition: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'

VectorLayerConfig

PropTypeDescription
namestringLayer display name
sourceSourceConfigData source (geojson, csv, directus, api…)
styleobjectMapLibre paint/layout properties
popupTemplatestringHTML popup with ${fieldName} placeholders
visiblebooleanInitial visibility (default: true)
fitToContentbooleanAuto-zoom to layer bounds
filterFilterObject | functionClient-side feature filter
searchInFieldsSearchInFieldsFields 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
}