Map

Docs / Map

Overview

The <x-map> component is the foundational building block for all maps. It initializes MapLibre GL JS, sets up the viewport, and provides the container for all child components like markers, popups, routes, clusters, arcs and GeoJSON layers. Children react to Livewire state: when your component re-renders, they update in place while the map itself is preserved (the map uses wire:ignore.self, so you never need to wrap it in wire:ignore). Until the style has loaded, a loading overlay is shown; you can customise or disable it.

Basic Usage

Tile Providers

Switch between built-in tile providers using the provider prop. You can also supply a custom MapLibre style (a URL or a style array) via the style prop.

ProviderDescription
carto-positronClean light basemap (default)
carto-voyagerColorful light basemap
carto-dark-matterDark basemap (the default dark_provider)
openfreemap-libertyOpenFreeMap vector style with 3D building extrusions; pair it with a pitched view
openfreemap-brightOpenFreeMap bright vector style
openfreemap-positronOpenFreeMap minimal light style
osm-rasterStandard OpenStreetMap raster tiles
blankTransparent style with no basemap (same as the blank prop)
CARTO basemaps are free for non-commercial use only. OpenFreeMap styles are free with no API key. See the carto_license option on the installation page.

Carto Positron (Light)

Carto Dark Matter

OpenFreeMap Liberty

Theme Support

The theme prop controls how the map responds to dark mode. With "auto" (default) the map follows a dark / light class or a data-theme attribute on <html>, swapping styles live and dispatching map:theme-changed. Set follow_system_theme to true in the config to also follow the OS preference when neither is present. Force a theme with "light" / "dark", or switch at runtime with the map:set-theme command.

  • Light mode uses provider (or light-style); dark mode uses dark-style, falling back to the configured dark_provider.
  • A style (or light-style) applies to both themes unless you also set dark-style.
  • Anywhere a style is accepted you can pass a provider key, e.g. dark-style="openfreemap-positron".

Globe Projection

Set projection="globe" to render the world as a sphere at low zoom. MapLibre transitions to a flat map as you zoom in. It pairs well with arcs.

Bounds & Camera

Use :bounds to fit an area when the map loads (instead of :center/:zoom), and :max-bounds to stop users panning away. Bounds are [[west, south], [east, north]]. :zoom accepts floats and 0.

Gesture props such as :drag-rotate, :touch-zoom-rotate, :pitch-with-rotate and :cooperative-gestures (Ctrl/⌘ + scroll to zoom, two fingers to pan on touch) are useful for maps embedded in long pages.

Blank Map

Add :blank="true" for a transparent style with no basemap. Combine it with <x-map-geojson> to build choropleths and diagrams where your data is the whole map.

blade
<x-map :blank="true" :center="[15, 25]" :zoom="0.6">
    <x-map-geojson data="https://example.com/countries.geojson" :interactive="true" />
</x-map>

Loading State

Until the map has loaded, a subtle pulsing-dots overlay is shown. It fades out when MapLibre fires load (the map element gets the lm-loaded class). You can replace it, restyle it, or turn it off.

Custom loader

Pass a <x-slot:loading> with any markup. Attributes on the slot (like class) are added to the overlay, which stays centered over the map:

Loading London…

Restyle the default

The default overlay reads these CSS custom properties, so you can theme it without new markup:

css
.lm-map {
    --lm-loader-bg: rgba(255, 255, 255, 0.85);  /* overlay background */
    --lm-loader-backdrop: none;                 /* default: blur(2px) */
    --lm-loader-color: #0a0a0a;                 /* dots / text colour */
    --lm-loader-dot-size: 0.5rem;
    --lm-loader-fade: 0.5s;                     /* fade-out duration */
}

Disable it

Use :loader="false" on a single map, or set 'loader' => false in config/livewire-mapcn.php to turn it off everywhere (a map can opt back in with :loader="true"). A <x-slot:loading> is always shown, even when the default loader is disabled. Lazy maps that haven't started yet show their loader as a placeholder until they come into view.

MapLibre Options

Anything without a dedicated prop can be passed straight to the MapLibre Map constructor with :options. These are merged last, so they win over the props.

blade
<x-map
    :options="['hash' => true, 'fadeDuration' => 0, 'maxTileCacheSize' => 200]"
    :attribution-compact="false"
    :loader="false"
/>

Props

PropTypeDefaultDescription
:center?arrayconfigInitial map center [lng, lat] (config default_center)
:zoomint|float|nullconfigInitial zoom level, floats and 0 allowed (config default_zoom)
:min-zoomint|float0Minimum zoom level
:max-zoomint|float22Maximum zoom level
provider?stringconfigBuilt-in provider (config default_provider, 'carto-positron')
stylearray|string|nullnullCustom MapLibre style URL, style array or provider key. Applies to both themes unless dark-style is set
light-stylearray|string|nullnullStyle for light mode
dark-stylearray|string|nullnullStyle for dark mode (falls back to dark_provider)
themestring'auto''light', 'dark', or 'auto'
projection?stringnull'globe' for a 3D globe, otherwise Mercator
:blankboolfalseTransparent style with no basemap
heightint|string|nullconfigfull (100%), an int (px) or any CSS value, e.g. 320px, 60vh
widthint|string'100%'CSS width (ints are px)
:bearingint|float0Initial bearing in degrees
:pitchint|float0Initial pitch in degrees
:max-pitchint|float|nullnullMaximum pitch
:bounds?arraynullFit [[w, s], [e, n]] on load
:bounds-paddingint40Padding (px) for :bounds
:max-bounds?arraynullRestrict panning to [[w, s], [e, n]]
:interactivebooltrueEnable mouse/touch interactions
:scroll-zoombooltrueAllow mouse wheel zoom
:double-click-zoombooltrueAllow double-click zoom
:drag-panbooltrueAllow panning by drag
:drag-rotatebooltrueAllow rotating with right-click / Ctrl + drag
:touch-zoom-rotatebooltrueAllow pinch zoom and rotate
:pitch-with-rotatebooltrueAllow pitch while rotating
:cooperative-gesturesboolfalseRequire Ctrl/⌘ + scroll to zoom and two fingers to pan
:render-world-copiesbooltrueRepeat the world horizontally when zoomed out
:attributionbooltrueShow the attribution control
:attribution-compactbooltrueCollapse attribution into an info button
:loader?boolconfig loaderShow the default loading overlay until the map has loaded. Use <x-slot:loading> for custom content (Loading State)
:eventsarray[]Extra MapLibre event names to forward as map:{event}
:optionsarray[]Raw options merged into the MapLibre Map constructor
classstring''Additional CSS classes