imumz/nova-4-card-map
A Laravel Nova 4 card that plots your records on an interactive map. Display models with latitude and longitude coordinates as markers directly on a dashboard card, giving you a quick geographic overview of your data at a glance.
This is a Nova 4 dashboard/detail card — it adds a map panel to the Nova UI. There is no server-side data model, no migrations, and no routes to wire up, so setup is shallow: install, register the card, configure the map.
Install
composer require imumz/nova-4-card-map
Requires Laravel Nova 4.x and a matching PHP version (Nova 4 means PHP 8.1+). Since the package ships built JS, you normally do not need to run npm in the host app — but confirm the repo actually contains a compiled dist/ before relying on that.
Register the card. Cards are registered either on a dashboard or on a resource. Dashboard is the common first use case:
// app/Providers/NovaServiceProvider.php (or a custom Dashboard class)
public function cards(): array
{
return [
\Imumz\Nova4CardMap\Nova4CardMap::make()
->width('2/3'),
];
}
Configure it. Nova cards are configured fluently or via withMeta(). Typical map knobs: center coordinates, zoom level, and marker list. Check the README for the exact methods, but the shape is almost always:
Nova4CardMap::make()
->withMeta([
'center' => [51.505, -0.09],
'zoom' => 12,
'markers' => [
['lat' => 51.5, 'lng' => -0.09, 'label' => 'London'],
],
]);
First real use case: put a dashboard card in front of support/ops so they see where your locations are at a glance. Once that renders, move to a resource detail card (see below) where markers are derived from the current model.
Where to look first in the repo: the card class (to see which withMeta keys the Vue component reads) and resources/js/components/Card.vue (to see the map library — Leaflet, Google Maps, Mapbox — and the prop names). Those two files define the entire public API.
Dashboard card (static config). The simplest pattern: fixed center/zoom and a hard-coded or config-driven marker array. Good for an "office locations" or "coverage area" panel. Put the marker array in a config file and read it in cards() so non-developers can edit locations.
Resource detail card (data-driven). This is where the card earns its keep. Add it to a resource's cards() method and feed that model's coordinates:
public function cards(NovaRequest $request): array
{
return [
Nova4CardMap::make()
->withMeta([
'center' => [$this->latitude, $this->longitude],
'zoom' => 15,
'markers' => [[
'lat' => $this->latitude,
'lng' => $this->longitude,
'label' => $this->name,
]],
]),
];
}
Note this pattern is not reactive — the card is built once when the detail page loads. If the user edits the latitude field on the same page, the map won't move until reload. Treat it as a read-only summary card.
Multiple instances. Because each card is its own instance with its own meta, you can stack several: a wide "all locations" dashboard card plus narrow per-site detail cards. Give each a distinct title with ->title() so they're distinguishable.
Custom marker payloads. The withMeta array is passed straight to the Vue component, so any extra keys you add (color, url, icon) survive the trip. Whether they render depends on the component's template — inspect Card.vue before promising a colored pin to a stakeholder.
Customising the component. Nova cards let you override the front-end via ->component('my-custom-map') and registering your own Vue component in the host app. This is the cleanest extension path: keep the package's card class, replace the view. It avoids forking.
Dashboard integration tip. Cards in a custom Dashboard class are just returned from cards(). If you already have a dashboard, drop the card in rather than creating a new one; you also get refreshWhenFiltersChange() / refreshWhenActionRuns() from the base Card for free (though see gotchas — the map may not actually re-fetch).
composer.json.dist/js/card.js, the card will silently render an empty box. Check composer.json for post-autoload-dump publish hooks and the package's nova.mix/webpack.mix.js. Fix: php artisan vendor:publish --tag=nova4-card-map-assets (tag name may differ) or build in the package directory.height: 100% container inside an auto-height card collapses to 0px and renders a blank white panel. If the map is invisible, inspect the container's computed height first, then the tile network requests..leaflet-*, z-index values especially) can leak into Nova's UI, causing dropdowns or modals to render under the map. Scope the card in your custom component, or set a modest z-index on .leaflet-pane.center/markers are the usual suspects when you pass a malformed withMeta. Then check the Network tab for tile 404s (bad coordinates or key). Laravel logs rarely show anything useful for card issues since it's all client-side.withMeta() for data, (2) ->component() + your own Vue file for styling/behaviour, (3) subclass the card class for server-side data shaping, (4) fork. Given the maintenance risk, (2) is almost always the right long-term move.How can I help you explore Laravel packages today?