NovaField Map 3.0.0

Laravel Nova 5  ·  MIT

A map field that behaves like a Nova field.

FieldMap reads your coordinate column, works out what shape it is in, and draws it. GeoJSON, "45.6495,13.7768", a [lat, lng] array or a spatial Point — all understood without being told. Make it editable and an administrator drops the pin themselves.

11.2kB gz per page
169tests passing
10tile providers
0keys required
WarehouseDetail
Name
Trieste Porto Vecchio
Location
+−
© OpenStreetMap
45.6495, 13.7768
Updated
2 hours ago

01  /  The smallest real thing

Two arguments. That is the whole field.

No type(), no handing the data in yourself. Name the field, name the column, and the resolver chain works out what it found.

app/Nova/Warehouse.php
use Gabrielesbaiz\NovaFieldMap\FieldMap;

public function fields(NovaRequest $request): array
{
    return [
        FieldMap::make('Location', 'coordinates'),
    ];
}
What renders
+−
© OpenStreetMap

The coordinates column can hold any of these. Nothing tells the field which:

'45.6495,13.7768'a string
[45.6495, 13.7768]a positional array
['lat' => 45.6495, 'lng' => 13.7768]a keyed array
'{"type":"Point","coordinates":[13.7768,45.6495]}'GeoJSON
new Point(45.6495, 13.7768)a spatial value object

02  /  Editable

Two more calls and an administrator places the pin.

2.x forced showOnUpdate to false and shipped a text input that did nothing. 3.0 gives you a real form field: click to place, drag to adjust, search for a place, or type the numbers.

Editable, with place search
FieldMap::make('Location', 'coordinates')
    ->editable()
    ->geocoder()
    ->height('400px')
What renders
+−
© OpenStreetMap

03  /  A whole relation

One marker per related record, clustered, clickable.

Each related record's attributes travel with its feature, so popups and per-marker styling address them by column name. linkToResource() makes a marker click open that record's detail page through Inertia.

A store locator
public static $with = ['branches'];

FieldMap::make('Branches', 'coordinates')
    ->relation('branches')
    ->popup('name')
    ->linkToResource()
    ->cluster(disableAtZoom: 12)

// popup('name') is escaped. Markup needs
// an explicit ->allowHtmlPopups().
What renders
+−
14
6
Porto Vecchio
© OpenStreetMap

04  /  Decide by driving it

Every method, every option, live.

The playground has a control for all 58 public methods. Change one and three things move at once: the chain you would paste into a resource, the field Nova would draw, and the payload the browser actually receives — generated by the same rules as mapMeta(), so the derived values behave exactly as they do in your app.

Preview

What Nova draws

Markers, clusters, heat, choropleth, the draw toolbar, the search box, the legend, the index column. Turn a thing on and it appears.

PHP

The chain to paste

Only the calls that differ from a default are emitted, with the right use statements, so what you copy is what you would have written.

Payload

All sixty variables

The meta array the component receives, with the computed keys flagged — clustering forced off, the canvas threshold, a keyless tile being dropped.

05  /  What changed in 3.0

A rewrite, driven by three things that were wrong.

01

Popups were an XSS hole

Leaflet's bindPopup() renders a string as HTML, and 2.x passed feature properties to it untouched. Anyone who could write that column could run JavaScript in an administrator's session. Content is now escaped in PHP; markup needs an explicit opt-in and is still sanitised in the browser.

02

It leaked on every navigation

The map was never removed on unmount, so each Inertia page change left a live Leaflet instance and its handlers on detached DOM. 3.0 calls map.remove() and disconnects both observers — and a test asserts it.

03

Every page paid for Leaflet

2.x shipped one 74.3 kB gzipped bundle on every Nova page, map or no map. The entry bundle is now 11.2 kB; Leaflet arrives only when a map is about to become visible.

06  /  When not to use this

If two number fields will do, use two number fields.

Showing a latitude and a longitude is not a reason to load a mapping library. Two Number fields are less JavaScript, less to go wrong, and an administrator who knows the coordinates can simply type them.

Use Nova's own fields when…

Number::make('Latitude')->step(0.000001),
Number::make('Longitude')->step(0.000001),
  • The coordinates are data, not a place anyone needs to see.
  • Nobody is verifying the location by looking at it.
  • Your index tables need a location column and nothing more.

Use FieldMap when…

FieldMap::make('Location', 'coordinates')
    ->editable()
    ->geocoder(),
  • Somebody has to confirm the warehouse is on the right side of the motorway.
  • Fifty branches need to be seen at once, and the gap noticed.
  • The person knows where the site is, but not its coordinates.
  • A delivery-zone polygon has to be checked against the estate.

Support this package

Free forever. Not free to maintain.

The work you never see is the work that keeps the map boring. Tile hosts change their URL templates. Leaflet ships a minor. Nova ships a major and the field payload shape moves under you. Somebody has to notice, upgrade, and re-run 169 tests before your admin panel renders a grey box on a Monday morning. It stays MIT either way.

Sponsoring buys that time — the compatibility passes, the issue triage, the day spent working out why one tile provider started rate-limiting. It does not buy features, because no feature is held back. It stays MIT either way.

FREE
⭐

Star the repo

Thirty seconds, and it is the first signal another Laravel developer looks at.

FREE
🐛

Open a good issue

A resource class, the column's contents and the browser console beat a screenshot every time.

❤️

Sponsor from $5

Recurring, cancellable, and it is what keeps this green across Nova majors.

🏢

Company tier

If your team ships this to clients, a company tier puts your logo here.

Why ask at all? This package is MIT and always will be. Nothing is paywalled, nothing phones home, and no map feature is held back for sponsors. Sponsorship buys maintenance time, not features — and if you cannot sponsor, the star and the bug report genuinely help.