mantine-map
Interactive maps for Mantine, powered by MapLibre GL. Markers, controls and polygons with the Mantine styles API.
Installation
Import the styles once in your app, after the Mantine core styles. mantine-map/styles.css already
includes the required maplibre-gl styles, so you do not need to import them separately:
MapLibre GL JS v6 loads its renderer worker from a URL rather than through the bundler's module graph,
so the URL must be supplied once before the first map is created. Without it the map mounts but never
draws any tiles. setWorkerUrl is re-exported from mantine-map for this:
With webpack 5, rspack or rsbuild, use
setWorkerUrl(new URL("maplibre-gl/dist/maplibre-gl-worker.mjs", import.meta.url).toString()). With
Next.js, copy both maplibre-gl-worker.mjs and maplibre-gl-shared.mjs from
node_modules/maplibre-gl/dist into public/ and point at them there: they must stay side by side,
since the worker imports the shared chunk as a sibling. This site itself avoids the copy by letting
Turbopack bundle the worker as a new Worker(new URL(...)) entry, which is tidier to deploy but relies
on internals of both Turbopack and maplibre; see docs/maplibre-worker-url.ts in the repository.
Note:
mantine-mapdoes not ship any map tiles. Pass a style URL from a tile provider (for example MapTiler or CARTO) via themapStyleprop. The demos below use the keyless CARTO Voyager and Dark Matter basemaps, swapped automatically with the Mantine color scheme.
Usage
Markers
Markers accept custom content and integrate Mantine Tooltip and Popover for interactive overlays.
Adding markers on click
Map reports clicks on the map through onMapClick, which receives the { longitude, latitude }
under the pointer, so the coordinate can be handed straight to a Map.Marker. The raw MapLibre
MapMouseEvent is passed as the second argument for pixel coordinates and the original DOM event. The
name keeps it distinct from onClick, which stays the plain DOM handler of the root element.
Markers are rendered inside the map, so clicking an existing marker fires onMapClick as well. The
demo below skips those clicks by checking whether the DOM event originated inside .maplibregl-marker.
Clicks on Map.Controls never reach the map and need no such check.
Click the map to drop a marker
Controls
Controls are built from Mantine ActionIcon and inherit the active theme. Compose them inside
Map.Controls and anchor them to any corner.
The library ships no icons, so each control takes its icon as children and you can use any icon set
(the demo below uses Tabler icons). Map.FullscreenControl also accepts a
function, so a different icon can be rendered per state. Wrap adjacent controls in
Map.ControlGroup to join them into a single segmented block.
Map keeps the live bearing on its root element as the --map-bearing CSS variable.
Map.CompassControl uses it to rotate its needle without re-rendering, and your own overlays can
consume it the same way: transform: rotate(calc(var(--map-bearing) * -1)).
Polygons
Use Map.Polygon to highlight an area. Colors accept Mantine color keys and are resolved to concrete
values for the WebGL renderer.