Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Livewire Maps Laravel Package

esadewater/livewire-maps

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require esadewater/livewire-maps
    

    Publish the config file (if needed):

    php artisan vendor:publish --provider="Esadewater\LivewireMaps\LivewireMapsServiceProvider"
    
  2. Basic Usage Register the component in your Livewire class:

    use Esadewater\LivewireMaps\LivewireMaps;
    
    public function mount()
    {
        $this->mapOptions = [
            'center' => [40.416775, -3.703790], // Madrid coordinates
            'zoom' => 12,
        ];
    }
    
    public function render()
    {
        return view('livewire.your-component')->layout('layouts.app');
    }
    
  3. First Blade View

    <livewire-maps wire:model="mapOptions" />
    

    Ensure you include the required JS/CSS in your layout:

    @livewireScripts
    @livewireStyles
    

First Use Case: Embedding a Simple Map

  • Use the component to display a basic map with markers.
  • Example:
    public $markers = [
        ['lat' => 40.416775, 'lng' => -3.703790, 'title' => 'Madrid'],
    ];
    
    <livewire-maps
        wire:model="mapOptions"
        wire:model.defer="markers"
        marker-options='{"icon": {"iconUrl": "/path/to/icon.png"}}'
    />
    

Implementation Patterns

Common Workflows

  1. Dynamic Marker Management

    • Update markers via Livewire properties:
      public function addMarker($lat, $lng, $title)
      {
          $this->markers[] = compact('lat', 'lng', 'title');
      }
      
    • Remove markers with array manipulation:
      public function removeMarker($index)
      {
          unset($this->markers[$index]);
      }
      
  2. Interactive Features

    • Click Events: Bind to map-clicked event:
      <livewire-maps
          wire:map-clicked="handleMapClick"
          wire:model="mapOptions"
      />
      
      public function handleMapClick($event)
      {
          $this->addMarker($event['lat'], $event['lng'], 'New Point');
      }
      
    • Marker Drag: Enable draggable markers:
      public $markerOptions = [
          'draggable' => true,
          'dragend' => 'updateMarkerPosition',
      ];
      
      public function updateMarkerPosition($event)
      {
          $index = $event['markerId'];
          $this->markers[$index]['lat'] = $event['lat'];
          $this->markers[$index]['lng'] = $event['lng'];
      }
      
  3. Integration with Laravel Backend

    • Save marker data to a database:
      public function saveMarkers()
      {
          foreach ($this->markers as $marker) {
              Marker::updateOrCreate(
                  ['id' => $marker['id'] ?? null],
                  $marker
              );
          }
      }
      
    • Load markers from a database:
      public function mount()
      {
          $this->markers = Marker::all()->toArray();
      }
      

Advanced Patterns

  1. Custom Map Layers

    • Use layer-options to add tiles or overlays:
      <livewire-maps
          wire:model="mapOptions"
          layer-options='{
              "tiles": [{
                  "url": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
                  "attribution": "&copy; <a href=&quot;https://www.openstreetmap.org/copyright&quot;>OpenStreetMap</a>"
              }]
          }'
      />
      
  2. Geocoding Integration

    • Reverse geocode clicked points:
      public function handleMapClick($event)
      {
          $address = $this->geocode($event['lat'], $event['lng']);
          $this->addMarker($event['lat'], $event['lng'], $address);
      }
      
      Use a service like Nominatim or a paid API (e.g., Google Maps).
  3. Performance Optimization

    • Debounce Rapid Updates: Use Livewire’s defer or debounce for marker updates:
      wire:model.defer="markers"
      
    • Lazy Loading: Load markers in chunks for large datasets:
      public function loadMoreMarkers()
      {
          $this->markers = Marker::offset($this->offset)->limit(50)->get()->toArray();
          $this->offset += 50;
      }
      

Gotchas and Tips

Common Pitfalls

  1. Missing Dependencies

    • Ensure Leaflet.js is loaded. The package assumes it’s included via CDN or your asset pipeline.
    • If using Laravel Mix/Vite, add:
      // resources/js/app.js
      import 'leaflet/dist/leaflet.css';
      import 'leaflet';
      
  2. Coordinate Format

    • Lat/Lng Order: Leaflet expects [lat, lng], not [lng, lat] (common in Google Maps).
    • Debugging: Use console.log in the browser to verify coordinates:
      <script>
          window.addEventListener('livewire:init', () => {
              Livewire.on('map-ready', (map) => {
                  console.log('Map center:', map.getCenter());
              });
          });
      </script>
      
  3. Livewire Property Binding

    • Two-Way Binding: Ensure wire:model is used for mutable options (e.g., center, zoom).
    • Immutable Options: Use wire:init or wire:ignore for static configs:
      <livewire-maps
          wire:init="initMap"
          wire:ignore="staticOptions"
      />
      
  4. Marker ID Conflicts

    • If dynamically adding/removing markers, ensure markerId is unique (e.g., use database IDs or UUIDs).

Debugging Tips

  1. Console Logs

    • Expose map events to the browser:
      <script>
          Livewire.on('map-event', (event) => {
              console.log('Event:', event);
          });
      </script>
      
    • Trigger events from Livewire:
      $this->dispatch('map-event', data: ['type' => 'custom', 'data' => $event]);
      
  2. Inspecting the Map Object

    • Access the Leaflet map instance via:
      <script>
          Livewire.on('map-ready', (map) => {
              console.log('Full map object:', map);
          });
      </script>
      
    • Add this to your Livewire component’s JS:
      document.addEventListener('livewire:init', () => {
          Livewire.hook('element.updated', (el) => {
              if (el.tagName === 'LIVEWIRE-MAPS') {
                  const map = el._x_dataStack[0].map;
                  console.log('Map instance:', map);
              }
          });
      });
      
  3. Common Errors

    • "Map container not found": Ensure the DOM element exists before the map initializes. Use wire:ignore or x-data to delay rendering.
    • Marker not updating: Verify Livewire properties are being modified correctly. Use {{ dd($this->markers) }} in a blade template to debug.

Extension Points

  1. Custom Directives

    • Extend the component with Alpine.js directives:
      <livewire-maps x-data="{ customData: null }" />
      <script>
          document.addEventListener('alpine:init', () => {
              Alpine.data('mapExtender', () => ({
                  init() {
                      Livewire.on('map-ready', (map) => {
                          this.customData = map;
                      });
                  }
              }));
          });
      </script>
      
  2. Leaflet Plugin Integration

    • Load additional Leaflet plugins dynamically:
      <script src="https://unpkg.com/leaflet-control-geocoder@2.0.0/dist/Control.Geocoder.js"></script>
      <livewire-maps wire:model="mapOptions" />
      <script>
          Livewire.on('map-ready', (map) => {
              L.control.geocoder().addTo(map);
          });
      </script>
      
  3. Server-Side Processing

    • Offload heavy computations (e.g., clustering) to the server:
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui