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

Ux Leaflet Map Laravel Package

symfony/ux-leaflet-map

Symfony UX package integrating Leaflet maps into your app with Stimulus controllers and Twig components. Easily render interactive maps, markers, and layers while keeping configuration in PHP/Twig and assets managed via Symfony’s UX tooling.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require symfony/ux-leaflet-map
    npm install --force  # Only if using Webpack Encore
    npm run watch       # Restart Encore if needed
    
  2. Configure DSN (.env):
    UX_MAP_DSN=leaflet://default
    
  3. Basic Twig usage (in a template):
    {{ ux_map(map, {'data-controller': 'map' }) }}
    
    Where map is a Symfony\UX\Map\Map object configured in your controller.

First Use Case: Simple Marker Map

// src/Controller/MapController.php
use Symfony\UX\Map\Map;
use Symfony\UX\Map\Point;
use Symfony\UX\Map\Marker;

$map = (new Map())
    ->center(new Point(48.8566, 2.3522)) // Paris coordinates
    ->zoom(12)
    ->addMarker(new Marker(new Point(48.8584, 2.2945), 'Eiffel Tower'));

return $this->render('map/index.html.twig', ['map' => $map]);

Implementation Patterns

1. Controller Integration

  • Dynamic Maps: Fetch geospatial data from a database and populate markers dynamically:
    $map = (new Map())->center(new Point($lat, $lng))->zoom(10);
    foreach ($locations as $location) {
        $map->addMarker(new Marker(new Point($location['lat'], $location['lng']), $location['name']));
    }
    
  • Event-Driven Workflows: Use Symfony’s event system to trigger actions on map interactions (e.g., marker click):
    $marker->on('click', function (MarkerClickEvent $event) {
        // Handle click (e.g., fetch details via AJAX)
    });
    

2. Stimulus Controller Extensions

  • Custom Markers: Override default marker icons via Stimulus:
    // assets/controllers/map_controller.js
    import { Controller } from '@hotwired/stimulus';
    
    export default class extends Controller {
        connect() {
            this.element.addEventListener('ux:map:marker:before-create', (event) => {
                const { definition, L } = event.detail;
                definition.bridgeOptions.icon = L.icon({ iconUrl: '/custom-icon.png' });
            });
        }
    }
    
    Register in Twig:
    {{ ux_map(map, {'data-controller': 'map' }) }}
    

3. Advanced Map Options

  • Custom Tile Layers: Replace OpenStreetMap with alternatives (e.g., Mapbox, Esri):
    $leafletOptions = (new LeafletOptions())
        ->tileLayer(new TileLayer(
            url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
            attribution: 'Custom Attribution'
        ));
    $map->options($leafletOptions);
    
  • Disable Default Controls: Hide zoom/attribution controls:
    $leafletOptions = (new LeafletOptions())
        ->zoomControl(false)
        ->attributionControl(false);
    

4. Integration with Symfony Forms

  • Location Picker: Combine with Symfony Forms for address input:
    {{ form_row(form.address) }}
    {{ ux_map(map, {'data-controller': 'map', 'data-map-action': 'set-form-value~form.address' }) }}
    
    Stimulus controller to sync form values:
    connect() {
        this.map = this.element.querySelector('[data-map]');
        this.map.addEventListener('click', (e) => {
            const latlng = e.latlng;
            this.element.dispatchEvent(new CustomEvent('set-form-value', {
                detail: { value: `${latlng.lat},${latlng.lng}` }
            }));
        });
    }
    

5. Performance Optimization

  • Lazy-Loading: Load map assets only when needed (e.g., on route-specific pages):
    {% if app.request.get('_route') == 'location_dashboard' %}
        {{ ux_map(map, {'data-controller': 'map' }) }}
    {% endif %}
    
  • Debounce Events: Reduce API calls for frequent map interactions (e.g., drag events):
    let debounceTimer;
    this.map.addEventListener('move', () => {
        clearTimeout(debounceTimer);
        debounceTimer = setTimeout(() => {
            // Fetch new data
        }, 300);
    });
    

Gotchas and Tips

Pitfalls

  1. Webpack Encore CSS Path Issue:

    • Error: Module not found: leaflet/dist/leaflet.min.css.
    • Fix: Add an alias in webpack.config.js:
      Encore.addAliases({
          'leaflet/dist/leaflet.min.css': 'leaflet/dist/leaflet.css',
      });
      
    • Alternative: Use AssetMapper (no Webpack) or CDN for Leaflet CSS/JS.
  2. Marker Icon Conflicts:

    • Issue: Setting bridgeOptions.icon on a marker that already has an icon triggers a warning.
    • Fix: Clear existing icon options first or use extra data to pass custom icons:
      $marker = new Marker($point, 'Label', ['icon_url' => '/custom-icon.png']);
      
  3. Symfony UX Version Mismatch:

    • Error: symfony/ux-leaflet-map v3.x requires Symfony 7.4+ and PHP 8.4+.
    • Fix: Downgrade to v2.x if using older versions:
      composer require symfony/ux-leaflet-map:^2.35
      
  4. Event Listener Leaks:

    • Issue: Forgetting to remove event listeners in Stimulus controllers can cause memory leaks.
    • Fix: Always call disconnect():
      disconnect() {
          this.element.removeEventListener('ux:map:marker:before-create', this._onMarkerBeforeCreate);
      }
      

Debugging Tips

  1. Inspect Map Events:

    • Use browser dev tools to listen for custom events:
      document.querySelector('[data-map]').addEventListener('ux:map:marker:click', (e) => {
          console.log('Marker clicked:', e.detail);
      });
      
  2. Leaflet Console Debugging:

    • Access the Leaflet map instance via Stimulus:
      connect() {
          this.map = this.element.querySelector('[data-map]').map;
          console.log(this.map); // Inspect methods/options
      }
      
  3. Twig Debugging:

    • Dump the map object to verify configuration:
      {{ dump(map) }}
      

Extension Points

  1. Custom Layers:

    • Extend Leaflet layers (e.g., GeoJSON) by overriding the Stimulus controller:
      _onLayerBeforeCreate(event) {
          const { definition, L } = event.detail;
          if (definition.type === 'geojson') {
              definition.bridgeOptions = {
                  style: (feature) => ({ color: feature.properties.color || '#3388ff' })
              };
          }
      }
      
  2. Third-Party Plugins:

    • Integrate Leaflet plugins (e.g., leaflet-routing-machine) by extending the Stimulus controller:
      connect() {
          this.map.on('load', () => {
              L.Routing.control({ ... }).addTo(this.map);
          });
      }
      
  3. Server-Side Rendering (SSR):

    • For Symfony UX Turbo, ensure map initialization runs only on the client:
      {% if app.request.isXmlHttpRequest or app.request.isTurboFrame %}
          {{ ux_map(map, {'data-controller': 'map' }) }}
      {% endif %}
      
  4. Testing:

    • Use Symfony’s browser kit to test map interactions:
      $client->executeScript("
          document.querySelector('[data-map]').dispatchEvent(new CustomEvent('ux:map:marker:click', {
              detail: { definition: { id: 'test-marker' } }
          }));
      ");
      $this->assertSelectorTextContains('h1', 'Marker clicked!');
      
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.
calliostro/spotify-bundle
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle