tessl install tessl/npm-react-leaflet@5.0.3React components for Leaflet maps
React components for Leaflet maps using React's declarative component model with full TypeScript support.
| Property | Value |
|---|---|
| Package | react-leaflet |
| Version | 5.0.0 |
| Type | npm |
| Language | TypeScript |
| Installation | npm install react-leaflet leaflet |
| Peer Dependencies | leaflet ^1.9.0, react ^19.0.0, react-dom ^19.0.0 |
| Bundle Size | ~15KB minified + gzipped |
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
import "leaflet/dist/leaflet.css";
function MyMap() {
return (
<MapContainer center={[51.505, -0.09]} zoom={13} style={{ height: "400px" }}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='© OpenStreetMap contributors'
/>
<Marker position={[51.505, -0.09]}>
<Popup>A sample popup</Popup>
</Marker>
</MapContainer>
);
}π See Quick Start Guide for detailed setup instructions
eventHandlers prop or custom hooksMapContainer (required root)
βββ TileLayer (base map)
βββ Markers & Popups (point features)
βββ Vector Shapes (circles, polygons, lines)
βββ Layer Groups (organize layers)
βββ Controls (UI elements)
βββ Media Overlays (images, video, SVG)| Component | Purpose | Key Props |
|---|---|---|
MapContainer | Root map container | center, zoom, style |
TileLayer | Base map tiles | url, attribution |
Marker | Point marker | position, icon |
Popup | Info popup | children, position |
Tooltip | Hover tooltip | children, permanent |
| Hook | Purpose |
|---|---|
useMap() | Access map instance |
useMapEvent(type, handler) | Single event handler |
useMapEvents(handlers) | Multiple event handlers |
π Hooks Reference
| Component | Description | Radius Unit |
|---|---|---|
Circle | Circle with geographic radius | Meters |
CircleMarker | Circle with pixel radius | Pixels |
Polyline | Multi-segment line | - |
Polygon | Filled polygon | - |
Rectangle | Rectangle from bounds | - |
| Component | Purpose |
|---|---|
LayersControl | Switch between layers |
ZoomControl | Zoom buttons |
ScaleControl | Map scale display |
AttributionControl | Attribution text |
π Controls Reference
// Core components
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
// Hooks
import { useMap, useMapEvent, useMapEvents } from "react-leaflet";
// Vector shapes
import { Circle, CircleMarker, Polyline, Polygon, Rectangle } from "react-leaflet";
// Layer groups
import { LayerGroup, FeatureGroup, GeoJSON, Pane } from "react-leaflet";
// Controls
import { LayersControl, ZoomControl, ScaleControl, AttributionControl } from "react-leaflet";
// Media overlays
import { ImageOverlay, SVGOverlay, VideoOverlay } from "react-leaflet";
// Core APIs (advanced)
import { useLeafletContext, createLayerComponent } from "@react-leaflet/core";// Position types
type LatLngExpression =
| LatLng
| [number, number]
| { lat: number; lng: number };
type LatLngBoundsExpression =
| LatLngBounds
| [LatLngExpression, LatLngExpression];
// Control position
type ControlPosition = 'topleft' | 'topright' | 'bottomleft' | 'bottomright';
// Path styling
interface PathOptions {
stroke?: boolean;
color?: string;
weight?: number;
opacity?: number;
fill?: boolean;
fillColor?: string;
fillOpacity?: number;
}npm install react-leaflet leaflet
npm install -D @types/leaflet # TypeScriptimport "leaflet/dist/leaflet.css";import L from "leaflet";
import icon from "leaflet/dist/images/marker-icon.png";
import iconShadow from "leaflet/dist/images/marker-shadow.png";
let DefaultIcon = L.icon({
iconUrl: icon,
shadowUrl: iconShadow,
});
L.Marker.prototype.options.icon = DefaultIcon;<MapContainer style={{ height: "400px", width: "100%" }}>function ChangeView({ center, zoom }) {
const map = useMap();
map.setView(center, zoom);
return null;
}
<MapContainer center={center} zoom={zoom}>
<ChangeView center={center} zoom={zoom} />
<TileLayer url="..." />
</MapContainer>const mapRef = useRef<Map | null>(null);
<MapContainer ref={mapRef} center={[51.505, -0.09]} zoom={13}>
{/* ... */}
</MapContainer>function MapEvents() {
useMapEvents({
click: (e) => console.log('Clicked at:', e.latlng),
zoomend: () => console.log('Zoom changed'),
});
return null;
}β οΈ MapContainer props are immutable - Use refs/hooks for dynamic updates
β οΈ Leaflet CSS required - Must import leaflet/dist/leaflet.css
β οΈ Components must be inside MapContainer - To access map context
β οΈ Coordinate order - Leaflet uses [lat, lng], GeoJSON uses [lng, lat]
β οΈ SSR - Use dynamic imports for Next.js/server-side rendering
β οΈ Performance - Use preferCanvas={true} for many vector shapes
| Issue | Solution |
|---|---|
| Map not displaying | Import Leaflet CSS, set explicit height |
| Markers not appearing | Fix default icon paths (see setup) |
| Events not firing | Ensure interactive={true}, check event handlers |
| Performance issues | Use preferCanvas={true}, implement clustering |
| TypeScript errors | Install @types/leaflet |
| SSR errors | Use dynamic imports, disable SSR for MapContainer |
Choose Circle vs CircleMarker:
Choose LayerGroup vs FeatureGroup:
Choose TileLayer vs ImageOverlay:
Choose Marker vs CircleMarker: