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

Nova Map Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

  • 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.

Implementation Patterns

  • Pin picker on the form, read-only map on detail. The same field serves both; use ->onlyOnDetail() / ->readonly() for the detail variant, and hide it from index() unless you're happy with a huge map column.
  • Two-column storage (recommended if the version supports it). Map the field to latitude/longitude attributes and keep the columns as DECIMAL(10,7). This keeps the data queryable (WHERE lat BETWEEN ...) instead of locked in JSON.
  • Single-column storage. Store the field value as a string like "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.
  • Hydration on edit. Confirm the stored value resolves into a marker on the edit form. If it doesn't, override resolveUsing() (and fillUsing() on save) so the map reads/writes exactly the format you store.
  • Validation lives in your FormRequest, not the field. Add ['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.
  • Geocoding is your job. This is a picker, not a geocoder. If admins need "search an address → drop pin," pair a text/address field with a Google Places autocomplete or a small custom field; store the formatted address separately.
  • Reusable pattern. Drop a trait or an abstract base resource method that adds the field + the two lat/lng columns consistently, so every resource behaves the same and you don't re-debug the format per model.
  • Public-side integration is separate. The package only handles the Nova admin UI. Read the stored coordinates and hand them to Leaflet/Google Maps on your front end; don't try to reuse the Nova field component outside Nova.

Gotchas and Tips

  • Maintenance risk is real. Last release 2020 and no Nova 4/5 guarantees — the Vue component may fail to mount or silently render nothing after a Nova upgrade. Pin the version in composer.json, and have a fallback plan (two number fields + a plain map link) if it breaks.
  • API key is exposed in the admin page. The Maps JS key is rendered client-side. Restrict it by HTTP referrer, enable only Maps JS (+ Places/Geocoding if needed), and set billing alerts — an unrestricted key on an admin page is a common way to wake up to a surprise bill.
  • Grey / zero-height map. If the field is inside a collapsed panel, an inactive tab, or a 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().
  • Precision loss. Use 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.
  • CSP / HTTPS. A strict Content-Security-Policy in Nova will block maps.googleapis.com. Allow script-src, connect-src, and img-src for Google domains, and serve Nova over HTTPS to avoid mixed-content blocks.
  • Debugging. First stop is the browser console (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.
  • Extension points. Subclass 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.
  • Test the empty-record path. A brand-new record with no coordinates is where broken map fields most often reveal themselves; test create-with-pin, create-without-pin, edit-with-existing-pin, and clear-pin, all four.
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.
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment