davidpiesse/nova-map
Nova Map adds an interactive map field to Laravel Nova resources for picking and storing latitude and longitude coordinates. Drop a marker, search for addresses, and save precise location data directly from your admin panel with minimal configuration.
Install into a Nova app that already has Nova working: composer require davidpiesse/nova-map. This is a Nova 2/3-era package (last release Nov 2020, ~113 stars), so smoke-test on your Nova version before committing to it.
Get a Google Maps API key with Maps JavaScript API enabled (add Places if you plan to do address search). Most versions read services.google.maps_key / GOOGLE_MAPS_KEY; otherwise pass the key explicitly on the field.
Decide your storage shape before writing the resource: either two decimal columns (latitude, longitude as DECIMAL(10,7)) or one string/JSON column. The field is forgiving about how you wire it, but your model casts and resolveUsing/fillUsing must agree.
Add the field to a resource:
use Davidpiesse\NovaMap\NovaMap;
public function fields(Request $request)
{
return [
NovaMap::make('Location'),
];
}
First use case to prove out: a Venue (or Store, Warehouse) resource where an admin drops a pin on a map, saves, and the detail view renders a read-only marker. If that round-trip works on create and edit, the rest is configuration.
->onlyOnDetail() / ->readonly() for the detail variant, and hide it from index() unless you're happy with a huge map column.latitude/longitude attributes and keep the columns as DECIMAL(10,7). This keeps the data queryable (WHERE lat BETWEEN ...) instead of locked in JSON."lat,lng" or JSON, and add an Eloquent cast / accessor so the rest of your app can read $venue->lat / $venue->lng without parsing. Whichever you pick, write a migration backfill if you change your mind later — this is the #1 source of "the field saves but nothing shows up" bugs.resolveUsing() (and fillUsing() on save) so the map reads/writes exactly the format you store.['required','numeric','between:-90,90'] for latitude and between:-180,180 for longitude, or a custom rule on the combined value. The map UI won't stop a bad value from being posted programmatically.composer.json, and have a fallback plan (two number fields + a plain map link) if it breaks.dependsOn block that is hidden at mount, the container has no size and the map renders blank. Make the field visible before init, or trigger a map resize when the container appears.0,0 is not "empty." If clearing the map writes 0,0 instead of null, records look "located" off the coast of Africa. Verify the empty state explicitly and normalise it in fillUsing().DECIMAL(10,7) (or DOUBLE) rather than FLOAT in MySQL; float rounding on save→load can move a pin enough to matter for delivery/geo queries.maps.googleapis.com. Allow script-src, connect-src, and img-src for Google domains, and serve Nova over HTTPS to avoid mixed-content blocks.Google Maps JavaScript API error: ...) and the Network tab for RefererNotAllowedMapError / ApiNotActivatedMapError. If the field renders but never saves, log the request payload — it's almost always a storage-format mismatch, not a map bug.NovaMap, use resolveUsing()/fillUsing() for custom storage, and vendor-publish or fork the Vue component (nova:vendor / rebuild) if you need UI changes — but budget for maintaining that fork, since upstream is unlikely to merge fixes.How can I help you explore Laravel packages today?