Blade Directives
The package provides two Blade directives for rendering maps in your views.
@leafletStyles
Outputs the Leaflet CSS <link> and JS <script> tags from the unpkg CDN. Place this in your <head>:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My App</title>
@leafletStyles
</head>This renders:
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" crossorigin=""></script>The version is controlled by the leaflet_version config value.
@leafletMap($map)
Renders a map instance. Outputs a container <div> with the map's dimensions and an inline <script> that initializes the Leaflet map:
<body>
<h1>Our Locations</h1>
@leafletMap($map)
</body>Each map is wrapped in an IIFE (Immediately Invoked Function Expression), so multiple maps on the same page don't conflict.
Full layout example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Store Locator</title>
@leafletStyles
</head>
<body>
<header>
<h1>Our Stores</h1>
</header>
<main>
@leafletMap($map)
</main>
</body>
</html>Multiple maps
Each @leafletMap() call is self-contained. You only need @leafletStyles once:
<head>
@leafletStyles
</head>
<body>
<div class="grid grid-cols-2 gap-4">
<div>
<h2>Main Office</h2>
@leafletMap($mainMap)
</div>
<div>
<h2>Branch Office</h2>
@leafletMap($branchMap)
</div>
</div>
</body>Using toHtml() directly
Since the Map class implements Htmlable, you can also use it directly in Blade without the directive:
{{-- These are equivalent: --}}
@leafletMap($map)
{!! $map->toHtml() !!}
{!! $map !!}In a Blade component
{{-- resources/views/components/map-card.blade.php --}}
@props(['map', 'title'])
<div class="rounded-lg shadow p-4">
<h3 class="text-lg font-bold mb-2">{{ $title }}</h3>
@leafletMap($map)
</div><x-map-card :map="$headquarters" title="Headquarters" />
<x-map-card :map="$warehouse" title="Warehouse" />Embedding maps in an iframe
When a page has many elements (dashboards, forms, sidebars), embedding the map inside an <iframe> keeps it isolated from the rest of the page's CSS and JavaScript. No package changes are needed — just create a dedicated route that serves a minimal HTML page with only the map.
1. Create a standalone map route
// routes/web.php
use arielmejiadev\LeafletForLaravel\LeafletMap;
use arielmejiadev\LeafletForLaravel\Marker;
Route::get('/map/embed/{id}', function (string $id) {
$map = LeafletMap::of($id)
->center(40.7484, -73.9857)
->zoom(14)
->width('100%')
->height('100%')
->marker(40.7484, -73.9857, fn (Marker $pin) => $pin
->popup('<b>Empire State Building</b>')
->icon('blue')
);
return view('maps.embed', compact('map'));
})->name('map.embed');2. Create the embed Blade view
This view renders a full HTML document with nothing but the map:
{{-- resources/views/maps/embed.blade.php --}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>html, body { margin: 0; padding: 0; width: 100%; height: 100%; }</style>
@leafletStyles
</head>
<body>
@leafletMap($map)
</body>
</html>3. Use the iframe in any page
{{-- resources/views/dashboard.blade.php --}}
<div class="grid grid-cols-3 gap-4">
<div class="col-span-2">
<h2>Store Locator</h2>
<iframe
src="{{ route('map.embed', 'store-locator') }}"
width="100%"
height="500"
style="border: none; border-radius: 8px;"
loading="lazy"
></iframe>
</div>
<aside>
<h2>Filters</h2>
{{-- sidebar content --}}
</aside>
</div>Passing dynamic data to the iframe
Use query parameters to make the embed configurable:
// routes/web.php
Route::get('/map/embed/{id}', function (string $id, Request $request) {
$lat = (float) $request->query('lat', 40.7484);
$lng = (float) $request->query('lng', -73.9857);
$zoom = (int) $request->query('zoom', 14);
$map = LeafletMap::of($id)
->center($lat, $lng)
->zoom($zoom)
->width('100%')
->height('100%')
->marker($lat, $lng);
return view('maps.embed', compact('map'));
})->name('map.embed');<iframe
src="{{ route('map.embed', ['id' => 'office', 'lat' => 41.8796, 'lng' => -87.6237, 'zoom' => 16]) }}"
width="100%"
height="400"
style="border: none;"
loading="lazy"
></iframe>Multiple iframes on the same page
Since each iframe loads its own document, you can embed as many maps as you need without conflicts:
<div class="grid grid-cols-2 gap-4">
<div>
<h3>New York</h3>
<iframe src="{{ route('map.embed', 'nyc') }}" width="100%" height="300" style="border: none;" loading="lazy"></iframe>
</div>
<div>
<h3>Los Angeles</h3>
<iframe src="{{ route('map.embed', 'la') }}" width="100%" height="300" style="border: none;" loading="lazy"></iframe>
</div>
</div>Tip: Use
loading="lazy"on iframes so the map only loads when the user scrolls it into view. This improves page performance when embedding multiple maps.