Weave 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

Filament Leaflet Laravel Package

eduardoribeirodev/filament-leaflet

A Filament package that adds interactive Leaflet maps to your admin panel. Drop a map field into forms to pick coordinates visually, search locations, and save latitude and longitude without writing custom JavaScript.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Filament form-field package that wraps Leaflet: you get a map picker, a geosearch input that turns place names into coordinates, and a Coordinate cast that round-trips the stored value back into the field. v5.2.2 is a bugfix release with no breaking changes, so it is a safe in-place upgrade from 5.2.x — but you do need to re-publish/rebuild the distributed CSS (see Gotchas).

Minimal path to first value:

  1. composer require eduardoribeirodev/filament-leaflet and run the package's install/publish command from the README so the JS/CSS assets land in public/. Leaflet is not bundled by Filament, so a missing asset publish is the #1 cause of a blank grey box.
  2. Cast the model column(s) to the package's Coordinate cast and add the map field to your form schema. Store as a single JSON/string column or as separate lat/lng columns — the cast supports both.
  3. Create/edit a record, drop a pin or use the search box, save, reopen. Confirm the pin is where you left it; that round trip through the cast is exactly what v5.2.2 hardened.

First real use case: an Address/Location resource where the user picks a point on the map and you later render it in an infolist table. Get the form + cast working before wiring up geosearch or labels — those are the two areas with the most behavioural nuance.

Look first at the field's own class and the cast class in the package source; they are small and reveal the supported fluent API (textMode(), coordinateLabelUsing(), geosearch options) faster than the README does.

Implementation Patterns

Cast-driven persistence. Put the cast on the model, not in the form. The field hydrates from and dehydrates to the cast, so the same value renders correctly in forms, infolists and API payloads. If your latitude/longitude live in non-standard columns, configure the cast's column names — 5.2.2 fixed custom cast columns being ignored, so if you were previously forced into latitude/longitude you can now migrate to your own names.

Geosearch: two different return shapes. This is the subtle one. When the select is populated from client-side options the value is scalar JSON; when you supply options via a PHP callback you get GeoSearchResult objects back. Read the coordinates off the object in the callback path and json_decode in the scalar path — do not assume one shape. Prior to 5.2.2 the input could bind the last search result regardless of which option was clicked, so pin ^5.2.2 if geosearch is user-facing, and write a regression test that selects a non-last option.

Labels and textMode(true). Use textMode(true) for read-only/table contexts where you want the label instead of an interactive map, and coordinateLabelUsing(fn ($coordinate) => ...) to control what that label says. The callback is the right hook for a stored address string, avoiding a runtime lookup entirely. For reverse geocoding, cache aggressively by rounded lat/lng (Nominatim's usage policy caps you at ~1 req/s and requires a User-Agent) and return the cached string; never geocode inside the callback on every table row render.

Pane/stacking control. Leaflet renders in panes with fixed z-index ordering. If you overlay polygons, markers and tooltips, register custom panes rather than nudging z-index in CSS — 5.2.2 corrected pane stacking including tooltip panes, so remove any !important z-index hacks you added as a workaround and retest.

Testing. Livewire tests can't run Leaflet, so assert on component state: set('data.coordinates', [...]), call('save'), then assert the model attribute. For the cast, test the round trip directly ($model->refresh()->coordinates) including a null/invalid stored value — 5.2.2 improved invalid-data handling rather than throwing.

Gotchas and Tips

  • Re-publish assets after upgrading. The CSS is distributed, not compiled by your app. If tooltips or panes still look wrong after 5.2.2, run the publish command and hard-refresh; a stale cached CSS file silently defeats the fix.
  • Version-pin geosearch. The "selects the last result" bug is a data-corruption class of bug (wrong coordinates saved silently). Require >=5.2.2 in composer.json rather than ^5.2.0.
  • null coordinates are legitimate. The cast now tolerates invalid/missing stored data. Don't assume the hydrated value is always an object — null-check before reading lat/lng in Blade/infolist renderers, and decide deliberately whether an empty field should save null or an empty array.
  • Hidden containers break the map. Fields inside inactive tabs, wizard steps or modals mount at zero height. Trigger map.invalidateSize() on the tab/modal shown event, or the map renders half-tiled and drag interactions feel offset.
  • Coordinate precision. Round to 6–7 decimals before persisting; full float precision bloats the JSON column and makes equality/duplicate checks useless.
  • Geosearch provider limits. Rate limits and attribution requirements are on you, not the package. Wrap the provider call behind a queued/cached lookup if search volume is user-driven, and always render the required attribution.
  • Extension point for custom labels. coordinateLabelUsing() is the sanctioned seam — prefer it over subclassing the field or overriding views, which will not survive package updates.
  • Upgrade checklist for 5.2.2: publish assets → drop z-index CSS hacks → verify geosearch selection with a non-last result → verify models with custom coordinate column names → re-save one record with an intentionally malformed coordinate to confirm graceful handling.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource