API Reference

Docs / Reference

Overview

The livewire-mapcn package provides a collection of Blade components for building interactive maps. All components must be nested inside the root <x-map> component. Everything inside the map is reactive: when your Livewire component re-renders, children update in place (use wire:key in loops and never wrap the map in wire:ignore).

Props are listed in kebab-case as you write them in Blade. Prefix a prop with : to pass a PHP expression (arrays, booleans, numbers), e.g. :zoom="12". Coordinates are always [lng, lat] arrays, except the lat/lng props of markers and popups.

Components

<x-map>

The root component. Give it a stable id attribute (used as mapId and for Livewire morphing). Other HTML attributes are rendered on the map element. See the Map page.

PropTypeDefaultDescription
centerarray|nullconfig default_center ([0, 0])Initial center [lng, lat]
zoomint|float|nullconfig default_zoom (7)Initial zoom level
min-zoomint|float0Minimum zoom
max-zoomint|float22Maximum zoom
providerstring|nullconfig default_provider ('carto-positron')Tile provider (see Tile Providers)
stylearray|string|nullnullCustom MapLibre style URL or JSON, used for both themes unless dark-style is set
light-stylearray|string|nullnullStyle used in light mode
dark-stylearray|string|nullnullStyle used in dark mode (defaults to config dark_provider)
themestring'auto'light, dark or auto (follows the page)
heightint|string|nullconfig default_height ('full')full (100%), an integer (px) or any CSS length
widthint|string'100%'An integer (px) or any CSS length
bearingint|float0Initial rotation in degrees
pitchint|float0Initial tilt in degrees
max-pitchint|float|nullnullMaximum tilt (MapLibre default when null)
interactivebooltrueEnable all user interaction
scroll-zoombooltrueZoom with the scroll wheel
double-click-zoombooltrueZoom on double-click
drag-panbooltruePan by dragging
drag-rotatebooltrueRotate with right-click/ctrl + drag
touch-zoom-rotatebooltruePinch to zoom and rotate on touch devices
pitch-with-rotatebooltrueAllow tilting while rotating
cooperative-gesturesboolfalseRequire ctrl/⌘ + scroll and two-finger pan (for maps embedded in scrolling pages)
render-world-copiesbooltrueRepeat the world horizontally when zoomed out
projectionstring|nullnullMap projection, e.g. globe or mercator
blankboolfalseUse an empty style with no basemap (for data-only maps)
max-boundsarray|nullnullRestrict panning to [[west, south], [east, north]]
boundsarray|nullnullInitial bounds to fit, overrides center/zoom
bounds-paddingint40Padding in px used with bounds
attributionbooltrueShow the attribution control
attribution-compactbooltrueUse the collapsible compact attribution
loaderbooltrueShow a loading indicator until the style has loaded
eventsarray[]Extra MapLibre events to forward as map:{event} (merged with config custom_events)
optionsarray[]Extra options merged into the MapLibre Map constructor
classstring''Extra CSS classes for the map element

<x-map-controls>

Built-in navigation controls. See the Controls page.

PropTypeDefaultDescription
zoombooltrueZoom in/out buttons
compassbooltrueCompass / reset-north button
visualize-pitchbooltrueTilt the compass icon with the map pitch
locatebooltrueGeolocation button
track-userbooltrueKeep following the user's location after locating
fullscreenboolfalseFullscreen button
scaleboolfalseScale bar
scale-unitstring'metric'metric, imperial or nautical
three-dboolfalse3D toggle button (fires map:3d-toggled)
three-d-pitchint|float60Pitch applied when 3D is enabled
three-d-bearingint|float-20Bearing applied when 3D is enabled
three-d-durationint1000Transition duration in ms
positionstring'top-right'top-left, top-right, bottom-left or bottom-right
classstring''Extra CSS classes

<x-map-control>

Places any markup over the map, styled as a control group. Inside it, the Alpine magic $map gives you the MapLibre instance.

PropTypeDefaultDescription
positionstring'top-left'top-left, top-right, bottom-left, bottom-right, top or bottom
groupbooltrueWrap the content in the bordered control-group style; set :group="false" for free-form panels
classstring''Extra CSS classes
blade
<x-map-control position="top-left">
    <button x-on:click="$map.easeTo({ pitch: 60, bearing: -20, duration: 1000 })">3D view</button>
</x-map-control>

<x-map-marker>

Accepts <x-marker-content>, <x-marker-tooltip>, <x-marker-popup> and <x-marker-label> as children. See the Markers page.

PropTypeDefaultDescription
latfloatrequiredLatitude
lngfloatrequiredLongitude
idstring|nullauto (UUID)Identifier sent with marker events
draggableboolfalseAllow dragging (fires drag events)
colorstring'#1A56DB'Color of the default dot
anchorstring'bottom'Which part of the marker sits on the coordinate (center, top, bottom-left, …)
offsetarray[0, 0]Pixel offset [x, y]
rotationfloat0Rotation in degrees
rotation-alignmentstring'auto'map, viewport or auto
pitch-alignmentstring'auto'map, viewport or auto
opacityfloat|nullnullMarker opacity (0–1)
classstring''Extra CSS classes

<x-marker-content>

Replaces the default dot with your own markup (the slot).

PropTypeDefaultDescription
classstring''Extra CSS classes for the wrapper

<x-marker-popup>

Popup opened when the marker is clicked; the slot is the content.

PropTypeDefaultDescription
max-widthstring'300px'Maximum popup width
close-buttonbooltrueShow a close button
close-on-click-mapbooltrueClose when the map is clicked
close-on-moveboolfalseClose when the map moves
anchorstring|nullnull (auto)Popup position relative to the marker; automatic when null
offsetint|array|nullnull (16px)Distance from the marker in px, or [x, y]
classstring''Extra CSS classes

<x-marker-tooltip>

Shown on hover.

PropTypeDefaultDescription
textstring|nullnullTooltip text; the slot content is used when omitted
anchorstring|nullnull (auto)Tooltip position relative to the marker
offsetint|array|nullnull (16px)Distance from the marker in px, or [x, y]
classstring''Extra CSS classes

<x-marker-label>

A permanent text label next to the marker.

PropTypeDefaultDescription
textstring|nullnullLabel text; the slot content is used when omitted
positionstring'bottom'top, bottom, left or right
classstring''Extra CSS classes

<x-map-route>

A polyline, optionally snapped to real roads. See the Routes page.

PropTypeDefaultDescription
coordinatesarrayrequiredWaypoints as [[lng, lat], …]
idstring|nullauto (UUID)Identifier for events and map:*-{id} commands
colorstring'#1A56DB'Line color
widthint|float4Line width in px
opacityfloat1.0Line opacity
dash-arrayarray|nullnullDash pattern, e.g. [2, 2]
line-capstring'round'butt, round or square
line-joinstring'round'bevel, round or miter
activeboolfalseRender with the active style
active-colorstring'#0F43C4'Color when active
active-widthint|float6Width when active
active-opacityfloat|nullnullOpacity when active (falls back to opacity)
active-dash-arrayarray|nullnullDash pattern when active
hover-colorstring|nullnullColor on hover
clickablebooltrueEnable click/hover events and the pointer cursor
with-stopsboolfalseDraw a dot at every waypoint
stop-colorstring'#1A56DB'Color of the stop dots
fetch-directionsboolfalseSnap to roads using OSRM
directions-profilestring'driving'driving, walking or cycling
directions-urlstring|nullconfig osrm_urlOSRM server base URL
alternativesboolfalseFetch and draw alternative routes
max-alternativesint2Maximum number of alternatives
alternative-colorstring'#94A3B8'Color of alternatives
alternative-opacityfloat0.5Opacity of alternatives
alternative-widthint|float3Width of alternatives
animateboolfalseAnimate the line drawing in
animate-durationint2000Draw animation duration in ms
progressfloat|nullnullFraction (0–1) of the route drawn as the progress overlay; null hides it
progress-colorstring|nullnullColor of the progress overlay
progress-widthint|float|nullnullWidth of the progress overlay
progress-opacityfloat|nullnullOpacity of the progress overlay
progress-dash-arrayarray|nullnullDash pattern of the progress overlay
progress-durationint0Animate progress changes over this many ms
before-idstring|nullnullInsert the line below this style layer
fit-boundsboolfalseFit the map to the route once it's ready

<x-map-route-marker>

A marker pinned to a point on its parent <x-map-route>. It follows the route as its coordinates or progress change. It accepts <x-marker-content>, <x-marker-tooltip>, <x-marker-popup> and <x-marker-label>.

PropTypeDefaultDescription
atstring|float'progress'start, end, progress (follows the route's progress) or a 0–1 fraction
route-idstring|nullnull (parent route)Attach to a route by id instead of the parent
idstring|nullauto (UUID)Identifier sent with marker events
align-to-routeboolfalseRotate the marker to the route's direction
colorstring'#1A56DB'Color of the default dot
anchorstring'center'Which part of the marker sits on the point
offsetarray[0, 0]Pixel offset [x, y]
rotationfloat0Rotation in degrees (added to the route bearing when aligned)
rotation-alignmentstring'auto'map, viewport or auto
pitch-alignmentstring'auto'map, viewport or auto
classstring''Extra CSS classes
blade
<x-map-route id="delivery" :coordinates="$path" :progress="$progress" :progress-duration="800">
    <x-map-route-marker at="start" color="#16a34a" />
    <x-map-route-marker at="progress" :align-to-route="true">
        <x-marker-tooltip text="Courier" />
    </x-map-route-marker>
    <x-map-route-marker at="end" color="#dc2626" />
</x-map-route>

<x-map-route-group>

Several selectable routes; each item of routes has coordinates and optional id and style keys. See the Routes page.

PropTypeDefaultDescription
routesarrayrequiredThe routes to render
idstring|nullauto (UUID)Identifier for events and map:update-route-group-{id}
selected-routeint|string0Index of the selected route (re-rendering with a new index selects it)
fit-boundsboolfalseFit the map to all routes once ready
alternative-colorstring'#94A3B8'Color of unselected routes
alternative-opacityfloat0.5Opacity of unselected routes
alternative-widthint|float3Width of unselected routes
line-capstring'round'Line cap
line-joinstring'round'Line join
clickablebooltrueSelect a route by clicking it
fetch-directionsboolfalseSnap every route to roads using OSRM
directions-profilestring'driving'driving, walking or cycling
directions-urlstring|nullconfig osrm_urlOSRM server base URL
animateboolfalseAnimate the selected route drawing in
animate-durationint2000Draw animation duration in ms
with-stopsboolfalseDraw a dot at every waypoint
stop-colorstring'#1A56DB'Color of the stop dots
active-colorstring'#0F43C4'Color of the selected route
active-widthint|float6Width of the selected route
hover-colorstring|nullnullColor on hover
activeboolfalseRender the selected route with the active style
dash-arrayarray|nullnullDash pattern

<x-map-route-list>

A panel listing a route's alternatives (with distance and duration) so the user can pick one. See the Routes page.

PropTypeDefaultDescription
route-idstring''Id of the <x-map-route> to list
map-idstring''Deprecated. The list now finds its route by id anywhere on the page
show-distancebooltrueShow each route's distance
show-durationbooltrueShow each route's duration
show-fastest-badgebooltrueMark the fastest route
show-time-diffbooltrueShow the time difference to the fastest route
positionstring'top-left'top-left, top-right, bottom-left or bottom-right
titlestring'Routes'Panel heading
widthstring''Panel width (CSS length)
container-classstring''Extra classes for the panel
header-classstring''Extra classes for the header
item-classstring''Extra classes for each item

<x-map-cluster-layer>

Clusters large point datasets. See the Clusters page.

PropTypeDefaultDescription
dataarray[]Items with lat/lng keys, or GeoJSON Features
urlstring|nullnullLoad GeoJSON from a URL instead of data
idstring|nullauto (UUID)Identifier for map:update-cluster-data-{id}
cluster-max-zoomint14Stop clustering above this zoom
cluster-radiusint50Cluster radius in px
cluster-min-pointsint2Minimum points to form a cluster
cluster-colorstring'#1A56DB'Cluster bubble color
cluster-colorsarray|nullnullColors stepped by cluster-thresholds, e.g. ['#3b82f6', '#1d4ed8', '#1e3a8a']
cluster-thresholdsarray|nullnullPoint counts where the next color starts, e.g. [100, 750]
cluster-text-colorstring'#FFFFFF'Count label color
cluster-size-stopsarray[[0, 18], [100, 26], [1000, 34]][count, radius] pairs for bubble size
point-colorstring'#1A56DB'Unclustered point color
point-stroke-colorstring'#FFFFFF'Unclustered point outline color
point-radiusint6Unclustered point radius
show-countbooltrueShow the count inside clusters
text-fontarray|nullnullFont stack for the count label
popup-propertystring|nullnullProperty shown in the point popup
popup-templatestring|nullconfig cluster_popup_viewHTML with {property} placeholders for the point popup
disable-popupboolfalseDon't open a popup on point click
click-zoombooltrueZoom in when a cluster is clicked
bufferint256Tile buffer size
tolerancefloat0.5Geometry simplification tolerance
max-features-to-inlineint2000Deprecated. Data is always embedded as a JSON script block
classstring''Extra CSS classes

<x-map-arc>

Curved lines between pairs of points. Each datum is ['id' => …, 'from' => [lng, lat], 'to' => [lng, lat], …]. Extra keys become feature properties you can use in paint expressions and in the tooltip/popup slots. See the Arcs page.

PropTypeDefaultDescription
dataarray[]The arcs to draw
idstring|nullauto (UUID)Identifier for events and map:update-arc-data-{id}
curvaturefloat0.2How strongly arcs bend (0 = straight)
samplesint64Points per arc (smoothness)
paintarray[]MapLibre line paint, merged over the defaults
layoutarray[]MapLibre line layout
hover-paintarray|nullnullPaint applied to the hovered arc
interactivebooltrueEnable hover/click events, tooltips and popups
before-idstring|nullnullInsert the layer below this style layer
fit-boundsboolfalseFit the map to all arcs

<x-map-geojson>

Renders any GeoJSON as fill, outline and circle layers. Pass false to a paint prop to drop that layer. Supports tooltip/popup slots. See the GeoJSON page.

PropTypeDefaultDescription
dataarray|string[]FeatureCollection, Feature, Geometry, or a URL
idstring|nullauto (UUID)Identifier for events and map:update-geojson-{id}
promote-idstring|nullnullFeature property to use as the feature id
fill-paintarray|false|nullnull (default style)Paint for polygon fills, or false to drop the layer
line-paintarray|false|nullnull (default style)Paint for lines and polygon outlines, or false
circle-paintarray|false|nullnull (default style)Paint for points, or false
fill-hover-paintarray|nullnullFill paint for the hovered feature
line-hover-paintarray|nullnullLine paint for the hovered feature
circle-hover-paintarray|nullnullCircle paint for the hovered feature
interactiveboolfalseEnable hover/click events, tooltips and popups
before-idstring|nullnullInsert the layers below this style layer
fit-boundsboolfalseFit the map to the data
fit-bounds-paddingint40Padding in px used with fit-bounds

Events

Events are dispatched once as bubbling DOM events that Livewire also receives. Listen with Alpine (@map:click) or Livewire (#[On('map:click')]). Every payload also includes mapId, except map:route-list-selected.

Map events

EventPayloadDescription
map:loadedcenter, zoomThe map is created and its first style has loaded
map:style-loadedstyle, darkA style finished loading (also after theme switches)
map:style-reloaded—The style was replaced via map:set-style
map:theme-changeddarkThe resolved light/dark theme changed (theme="auto")
map:clicklat, lng, lngLat, pointUser clicked on the map
map:double-clicklat, lngUser double-clicked on the map
map:right-clicklat, lngUser right-clicked (context menu) on the map
map:movelat, lngFired continuously while the map moves (throttled)
map:center-changedlat, lngFired once movement ends
map:bounds-changednorth, south, east, westVisible bounds after movement ends
map:viewport-changedcenter, zoom, bearing, pitchFull camera state after movement ends; center is [lng, lat]
map:zoomzoomFired continuously while zooming (throttled)
map:zoom-changedzoomFired once zooming ends
map:drag-endlat, lng, zoomUser finished dragging the map
map:bearing-changedbearingThe map was rotated (throttled)
map:pitch-changedpitchThe map was tilted (throttled)
map:3d-toggledenabledThe 3D button of <x-map-controls :three-d="true"> was toggled
map:locate-successlat, lng, accuracyThe locate control found the user
map:locate-errorcode, messageGeolocation failed or was denied
map:{event}MapLibre event dataExtra MapLibre events forwarded via custom_events / :events

Marker & popup events

EventPayloadDescription
map:marker-clickedid, lat, lngA marker was clicked
map:marker-mouseenterid, lat, lngPointer entered a marker
map:marker-mouseleaveidPointer left a marker
map:marker-drag-startid, lat, lngDragging a draggable marker started
map:marker-dragid, lat, lngFired while a marker is dragged (throttled)
map:marker-drag-endid, lat, lngA draggable marker was released
map:marker-popup-openidA marker popup opened
map:marker-popup-closeidA marker popup closed
map:popup-openidA standalone <x-map-popup> opened
map:popup-closeidA standalone popup closed

Route events

EventPayloadDescription
map:route-clickedid, lat, lng, coordinates, pointA route line was clicked
map:route-mouseenteridPointer entered a route
map:route-mouseleaveidPointer left a route
map:route-directions-readyid, geometry, distance, duration, alternativesDirections were fetched from OSRM
map:route-directions-errorid, messageFetching directions failed (falls back to straight lines)
map:route-alternative-selectedid, alternativeIndex, previousIndex, geometry, distance, durationAn alternative route became the primary route
map:route-updatedidA map:update-route-data-{id} command was applied
map:route-group-selection-changedgroupId, selectedRouteId, selectedIndex, previousRouteId, previousIndex, distance, durationThe selected route of a route group changed
map:route-group-directions-readygroupId, routesAll routes of a group were resolved
map:route-list-selectedrouteId, selectedIndex, previousIndex, distance, durationA route was picked in <x-map-route-list> (no mapId)

Arc, GeoJSON & cluster events

EventPayloadDescription
map:arc-clickedid, arc, lat, lngAn arc was clicked; arc is the original datum
map:arc-hoveredid, arc, lat, lngPointer moved onto an arc; on leave arc is null
map:geojson-clickedid, feature, lat, lngA feature was clicked; feature is {id, properties, geometry}
map:geojson-hoveredid, feature, lat, lngPointer moved onto a feature; on leave feature is null
map:cluster-clickedcluster_id, lat, lng, countA cluster bubble was clicked
map:cluster-expandedcluster_id, zoomThe map zoomed in to expand a cluster
map:cluster-point-clickedfeature_id, lat, lng, propertiesAn unclustered point was clicked

Commands

Dispatch these from Livewire with $this->dispatch(), using named arguments or a single array. See Targeting a Map.

Map commands

Each accepts an optional mapId. Without it the command applies to every map on the page.

CommandPayloadDescription
map:fly-tocenter, zoom, bearing, pitch, …Animate the camera along a flight path (MapLibre flyTo options)
map:ease-tocenter, zoom, bearing, pitch, …Animate the camera smoothly (MapLibre easeTo options)
map:jump-tocenter, zoom, bearing, pitch, …Move the camera instantly (MapLibre jumpTo options)
map:fit-boundsbounds, padding, …Fit [[west, south], [east, north]] in view; padding defaults to 40
map:set-zoomzoomSet the zoom level
map:set-centercenterSet the center ([lng, lat])
map:set-bearingbearingSet the rotation in degrees
map:set-pitchpitchSet the tilt in degrees
map:set-stylestyleReplace the style (URL or style JSON); fires map:style-reloaded
map:set-themethemeSwitch to light, dark or auto
map:resize—Recalculate the map size (after showing a hidden container)
map:callmethod, argsCall any public MapLibre Map method, e.g. method: 'setMaxZoom', args: [12]

Component commands

These target a component by the id you gave it, so give dynamic routes, arcs, GeoJSON and cluster layers an explicit id.

CommandPayloadDescription
map:update-route-data-{id}coordinates, color, width, progress, progressDuration, …Update a route's coordinates and/or style
map:route-progress-{id}progress, durationAnimate the progress overlay to progress (0–1) over duration ms
map:select-route-{id}indexMake an alternative route the primary one
map:force-animateid?, duration?Replay the draw animation of one route/group, or of all animated ones
map:update-route-group-{id}selectedRoute, routesChange the selected route or patch route styles in a group
map:update-arc-data-{id}data (or a plain array)Replace the arcs of an <x-map-arc>
map:update-geojson-{id}data (or a GeoJSON object)Replace the data of an <x-map-geojson>
map:update-cluster-data-{id}data (or a FeatureCollection)Replace the points of a cluster layer (send GeoJSON, e.g. GeoJSON::fromArray($points))

Example: Fly To

php — Livewire Component
// In Livewire Component
public function centerOnPilot()
{
    $this->dispatch('map:fly-to',
        mapId: 'main-map', // optional
        center: [-0.09, 51.5],
        zoom: 12,
        essential: true,
    );
}

JavaScript API

APIReturnsDescription
$map (Alpine magic)Map | nullMapLibre instance of the nearest enclosing map
x-map-resize (Alpine directive)—Resize the enclosing map when the expression becomes truthy
LivewireMap.getMap(id)Map | nullMapLibre instance of a map by id
LivewireMap.getRoute(id)controller | nullRoute controller: setProgress(value, durationMs), selectRoute(index), animate(duration?), pointAt(at), fitBounds()
LivewireMap.waitForMap(id, callback)—Run callback(map) once the map exists and its style has loaded. Works across wire:navigate; id may be null for the first map
LivewireMap.mapsobjectRegistry of all maps by id
LivewireMap.versionstringPackage JavaScript version

More examples on the Advanced page.

Tile Providers

Built-in tile providers you can use with the provider prop:

ProviderDescription
carto-positronLight, minimal basemap (default)
carto-voyagerClean, labelled basemap
carto-dark-matterDark basemap (default for dark mode)
openfreemap-libertyOpenFreeMap style with 3D building extrusions
openfreemap-brightColorful OpenFreeMap style
openfreemap-positronLight OpenFreeMap style
osm-rasterOpenStreetMap raster tiles
blankEmpty style with no basemap
customUse with style prop for custom MapLibre JSON
CARTO basemaps are free for non-commercial use. Commercial apps need a CARTO enterprise license or another provider, such as OpenFreeMap.

Configuration

Keys in config/livewire-mapcn.php:

KeyDefaultDescription
default_provider'carto-positron'Provider used when provider is not set
dark_provider'carto-dark-matter'Provider used in dark mode
default_height'full'Map height when height is not set
default_zoom7Initial zoom
default_center[0, 0]Initial center [lng, lat]
follow_system_themefalseWith theme="auto", also follow the OS color scheme when the page sets no theme
osrm_url'https://router.project-osrm.org'OSRM server for directions
cluster_popup_viewnullDefault Blade view for cluster point popups
custom_events[]Extra MapLibre events forwarded as map:{event} on all maps
maplibre_version'6.14.0'MapLibre GL JS version loaded from the CDN
load_from_cdntrueSet to false if you bundle MapLibre yourself (as window.maplibregl)
cdn_url / cdn_css_urlnullPin exact MapLibre JS/CSS URLs
inject_assets'route'route (served by the package) or published (from public/vendor)