React components for MapLibre GL JS and Mapbox GL JS that provide a React-friendly API wrapper for interactive mapping applications
—
Core mapping components for building interactive map applications with either Mapbox GL JS or MapLibre GL JS backends. These components provide identical APIs with backend-specific optimizations.
The foundational map component that renders the interactive map and serves as a container for all other map elements.
/**
* Main map component providing interactive mapping functionality
* Supports both controlled and uncontrolled patterns with comprehensive event handling
*/
interface MapProps extends MapInitOptions, MapboxProps, GlobalSettings {
/** Map library instance or promise resolving to map library */
mapLib?: MapLib | Promise<MapLib>;
/** Whether to reuse map instances for performance optimization */
reuseMaps?: boolean;
/** Map container DOM id */
id?: string;
/** Container CSS styles */
style?: CSSProperties;
/** Child components (markers, popups, controls, etc.) */
children?: React.ReactNode;
}
interface MapRef {
/** Get the underlying map instance for imperative operations */
getMap(): MapInstance;
}
function Map(props: MapProps): JSX.Element;Key Map Props:
interface MapInitOptions {
/** Initial longitude */
longitude?: number;
/** Initial latitude */
latitude?: number;
/** Initial zoom level */
zoom?: number;
/** Initial bearing in degrees */
bearing?: number;
/** Initial pitch in degrees */
pitch?: number;
/** Map style URL or object */
mapStyle?: string | any;
/** Mapbox access token (Mapbox only) */
mapboxAccessToken?: string;
}
interface MapboxProps extends MapCallbacks {
/** Current view state for controlled component */
viewState?: ViewState;
/** Initial view state for uncontrolled component */
initialViewState?: ViewState;
/** Interactive behavior settings */
interactive?: boolean;
scrollZoom?: boolean | ScrollZoomOptions;
boxZoom?: boolean;
dragRotate?: boolean;
dragPan?: boolean | DragPanOptions;
keyboard?: boolean;
doubleClickZoom?: boolean;
touchZoomRotate?: boolean | TouchZoomRotateOptions;
touchPitch?: boolean | TouchPitchOptions;
/** Constraints */
minZoom?: number;
maxZoom?: number;
minPitch?: number;
maxPitch?: number;
maxBounds?: LngLatBoundsLike;
/** Styling */
cursor?: string;
/** Animation */
transitionDuration?: number;
transitionInterpolator?: any;
/** Callbacks */
onLoad?: () => void;
onError?: (error: ErrorEvent) => void;
onResize?: () => void;
onRemove?: () => void;
onData?: (event: MapStyleDataEvent | MapSourceDataEvent) => void;
onStyleData?: (event: MapStyleDataEvent) => void;
onSourceData?: (event: MapSourceDataEvent) => void;
}Displays markers at specific geographic coordinates with customizable appearance and behavior.
/**
* Map marker component for displaying points of interest
* Supports dragging, custom styling, and event handling
*/
interface MarkerProps {
/** Marker longitude */
longitude: number;
/** Marker latitude */
latitude: number;
/** Visual positioning */
anchor?: 'center' | 'top' | 'bottom' | 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
offset?: PointLike;
/** Appearance */
color?: string;
scale?: number;
rotation?: number;
rotationAlignment?: 'map' | 'viewport' | 'auto';
pitchAlignment?: 'map' | 'viewport' | 'auto';
/** Behavior */
draggable?: boolean;
clickTolerance?: number;
/** Events */
onClick?: (event: MarkerEvent) => void;
onDragStart?: (event: MarkerDragEvent) => void;
onDrag?: (event: MarkerDragEvent) => void;
onDragEnd?: (event: MarkerDragEvent) => void;
/** Styling */
style?: CSSProperties;
className?: string;
children?: React.ReactNode;
}
function Marker(props: MarkerProps): JSX.Element;Displays information popups attached to specific geographic coordinates or markers.
/**
* Map popup component for displaying contextual information
* Can be anchored to coordinates or follow markers
*/
interface PopupProps {
/** Popup longitude */
longitude: number;
/** Popup latitude */
latitude: number;
/** Positioning */
anchor?: 'center' | 'top' | 'bottom' | 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
offset?: PointLike;
/** Appearance */
maxWidth?: string;
className?: string;
style?: CSSProperties;
/** Behavior */
closeButton?: boolean;
closeOnClick?: boolean;
closeOnMove?: boolean;
focusAfterOpen?: boolean;
/** Events */
onClose?: () => void;
onOpen?: () => void;
/** Content */
children?: React.ReactNode;
}
function Popup(props: PopupProps): JSX.Element;Built-in control components for common map interactions and UI elements.
/**
* Navigation control with zoom and compass functionality
*/
interface NavigationControlProps {
position?: ControlPosition;
showCompass?: boolean;
showZoom?: boolean;
visualizePitch?: boolean;
}
function NavigationControl(props: NavigationControlProps): JSX.Element;
/**
* Geolocation control for user location tracking
*/
interface GeolocateControlProps {
position?: ControlPosition;
positionOptions?: PositionOptions;
fitBoundsOptions?: any;
trackUserLocation?: boolean;
showAccuracyCircle?: boolean;
showUserLocation?: boolean;
onGeolocate?: (event: GeolocateResultEvent) => void;
onError?: (event: GeolocateErrorEvent) => void;
onTrackUserLocationStart?: (event: GeolocateEvent) => void;
onTrackUserLocationEnd?: (event: GeolocateEvent) => void;
}
function GeolocateControl(props: GeolocateControlProps): JSX.Element;
/**
* Fullscreen toggle control
*/
interface FullscreenControlProps {
position?: ControlPosition;
container?: HTMLElement;
}
function FullscreenControl(props: FullscreenControlProps): JSX.Element;
/**
* Scale indicator control
*/
interface ScaleControlProps {
position?: ControlPosition;
maxWidth?: number;
unit?: 'imperial' | 'metric' | 'nautical';
}
function ScaleControl(props: ScaleControlProps): JSX.Element;
/**
* Attribution control for map data credits
*/
interface AttributionControlProps {
position?: ControlPosition;
compact?: boolean;
customAttribution?: string | string[];
}
function AttributionControl(props: AttributionControlProps): JSX.Element;Additional controls available only when using MapLibre GL JS backend.
/**
* Terrain control for 3D terrain visualization (MapLibre only)
*/
interface TerrainControlProps {
position?: ControlPosition;
source?: string;
exaggeration?: number;
}
function TerrainControl(props: TerrainControlProps): JSX.Element;
/**
* Logo control for displaying MapLibre logo (MapLibre only)
*/
interface LogoControlProps {
position?: ControlPosition;
}
function LogoControl(props: LogoControlProps): JSX.Element;Components for adding and styling data on the map.
/**
* Data source component for providing data to map layers
* Extends SourceSpecification from MapBox/MapLibre with React-specific props
*/
interface SourceProps extends SourceSpecification, CanvasSourceSpecification {
/** Optional source ID, auto-generated if not provided */
id?: string;
/** Child Layer components that use this source */
children?: React.ReactNode;
}
function Source(props: SourceProps): JSX.Element;
/**
* Map layer component for styling and displaying source data
* Extends LayerSpecification from MapBox/MapLibre with React-specific props
*/
interface LayerProps extends LayerSpecification, CustomLayerInterface {
/** Optional layer ID, auto-generated if not provided */
id?: string;
/** Optional source ID, inherited from parent Source if not provided */
source?: string;
/** Insert layer before this layer ID for z-ordering */
beforeId?: string;
}
function Layer(props: LayerProps): JSX.Element;React hooks and context providers for advanced map integration.
/**
* Hook for accessing the current map instance
* Must be used within a Map component's children
*/
function useMap(): MapRef;
/**
* Hook for creating and managing custom map controls
* Handles control lifecycle and positioning
*/
function useControl<T extends IControl>(
onCreate: (map: MapInstance) => T,
onRemove?: (control: T) => void,
options?: {position?: ControlPosition}
): T;
/**
* Context provider for managing multiple map instances
* Enables map sharing and coordination between components
*/
interface MapProviderProps {
children: React.ReactNode;
}
function MapProvider(props: MapProviderProps): JSX.Element;Basic Map with Markers:
import React from 'react';
import Map, { Marker, Popup, NavigationControl } from 'react-map-gl/mapbox';
function InteractiveMap() {
const [selectedMarker, setSelectedMarker] = React.useState(null);
const markers = [
{id: 1, longitude: -100, latitude: 40, title: "Marker 1"},
{id: 2, longitude: -95, latitude: 35, title: "Marker 2"}
];
return (
<Map
initialViewState={{
longitude: -100,
latitude: 40,
zoom: 4
}}
style={{width: '100%', height: 400}}
mapStyle="mapbox://styles/mapbox/streets-v12"
mapboxAccessToken="YOUR_TOKEN"
>
{markers.map(marker => (
<Marker
key={marker.id}
longitude={marker.longitude}
latitude={marker.latitude}
onClick={() => setSelectedMarker(marker)}
/>
))}
{selectedMarker && (
<Popup
longitude={selectedMarker.longitude}
latitude={selectedMarker.latitude}
onClose={() => setSelectedMarker(null)}
>
<div>{selectedMarker.title}</div>
</Popup>
)}
<NavigationControl position="top-right" />
</Map>
);
}Advanced Data Visualization:
import React from 'react';
import Map, { Source, Layer } from 'react-map-gl/maplibre';
function DataVisualization() {
const geojsonData = {
type: 'FeatureCollection',
features: [
// ... GeoJSON features
]
};
const layerStyle = {
id: 'data-layer',
type: 'fill',
paint: {
'fill-color': ['get', 'color'],
'fill-opacity': 0.8
}
};
return (
<Map
initialViewState={{longitude: -100, latitude: 40, zoom: 4}}
style={{width: '100%', height: 400}}
mapStyle="https://demotiles.maplibre.org/style.json"
>
<Source id="data-source" type="geojson" data={geojsonData}>
<Layer {...layerStyle} />
</Source>
</Map>
);
}type ControlPosition =
| 'top-left'
| 'top-right'
| 'bottom-left'
| 'bottom-right';
interface IControl {
onAdd(map: MapInstance): HTMLElement;
onRemove(map: MapInstance): void;
getDefaultPosition?(): ControlPosition;
}
interface ScrollZoomOptions {
around?: 'center';
}
interface DragPanOptions {
linearity?: number;
easing?: (t: number) => number;
maxSpeed?: number;
deceleration?: number;
}
interface TouchZoomRotateOptions {
around?: 'center';
}
interface TouchPitchOptions {
around?: 'center';
}
// Source and Layer types from MapBox/MapLibre
interface SourceSpecification {
type: 'vector' | 'raster' | 'raster-dem' | 'geojson' | 'image' | 'video';
url?: string;
tiles?: string[];
bounds?: [number, number, number, number];
scheme?: 'xyz' | 'tms';
minzoom?: number;
maxzoom?: number;
attribution?: string;
// Additional properties vary by source type
}
interface CanvasSourceSpecification {
type: 'canvas';
coordinates: [[number, number], [number, number], [number, number], [number, number]];
animate?: boolean;
canvas: string | HTMLCanvasElement;
}
interface LayerSpecification {
id: string;
type: 'fill' | 'line' | 'symbol' | 'circle' | 'heatmap' | 'fill-extrusion' | 'raster' | 'hillshade' | 'background' | 'sky';
source?: string;
'source-layer'?: string;
minzoom?: number;
maxzoom?: number;
filter?: any[];
layout?: Record<string, any>;
paint?: Record<string, any>;
}
interface CustomLayerInterface {
id: string;
type: 'custom';
renderingMode?: '2d' | '3d';
onAdd?(map: MapInstance, gl: WebGLRenderingContext): void;
onRemove?(map: MapInstance, gl: WebGLRenderingContext): void;
prerender?(gl: WebGLRenderingContext, matrix: number[]): void;
render(gl: WebGLRenderingContext, matrix: number[]): void;
}Install with Tessl CLI
npx tessl i tessl/npm-react-map-gl