codewithdennis/filament-simple-map
Installation:
composer require codewithdennis/filament-simple-map
php artisan vendor:publish --tag="filament-simple-map-config"
Add your Google Maps API key to .env:
GOOGLE_MAPS_EMBED_API_KEY=your_api_key_here
First Use Case: Add the map action to a Filament resource or page:
use CodeWithDennis\FilamentSimpleMap\Actions\MapAction;
public static function getActions(): array
{
return [
MapAction::make('view_map')
->label('View Location')
->queryParam('latitude')
->queryParam('longitude'),
];
}
Where to Look First:
config/filament-simple-map.php for configuration options.src/Actions/MapAction.php for customization hooks.Basic Map Integration: Use the default action for displaying a single location:
MapAction::make('map')
->latitude($record->latitude)
->longitude($record->longitude)
->zoom(12)
->height('400px')
Dynamic Data Binding: Bind map coordinates dynamically (e.g., from a form or API):
MapAction::make('map')
->queryParam('lat')
->queryParam('lng')
->url(fn (Page $page) => $page->getUrl(['lat' => $page->lat, 'lng' => $page->lng]))
Customizing the Map URL: Override the default Google Maps embed URL:
MapAction::make('map')
->mapUrl(fn (string $lat, string $lng) => "https://custom-maps-api.com/?lat=$lat&lng=$lng")
Integration with Filament Forms:
Combine with a TextInput for manual coordinate entry:
use Filament\Forms\Components\TextInput;
TextInput::make('latitude')
->required()
->afterStateUpdated(fn (Page $record, $state) => $record->save())
->extraAttributes(['data-action' => 'map-action-update']);
Multi-Record Maps: Use in a table action to show locations for multiple records:
Table::make([
'name',
'latitude',
'longitude',
])
->actions([
MapAction::make('view')
->latitude(fn ($record) => $record->latitude)
->longitude(fn ($record) => $record->longitude),
]);
GOOGLE_MAPS_EMBED_API_KEY=your_key?referer=yourdomain.com
latitude/longitude are null:
MapAction::make('map')
->latitude(fn ($record) => $record->latitude ?? 0)
->longitude(fn ($record) => $record->longitude ?? 0)
'50vh') to adapt to screen size:
MapAction::make('map')->height('50vh')
MapAction::make('map')
->mapUrl(fn ($lat, $lng) => "https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3022.215!2d$lng!3d$lat!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0!2z!5e0!3m2!1s$language!2s$country!4v1234567890")
API Key Restrictions:
Coordinate Validation:
latitude > 90) will break the map.use Illuminate\Support\Facades\Validator;
$validator = Validator::make(['lat' => $lat, 'lng' => $lng], [
'lat' => 'required|numeric|between:-90,90',
'lng' => 'required|numeric|between:-180,180',
]);
Caching:
MapAction::make('map')
->mapUrl(fn ($lat, $lng) => "https://www.google.com/maps/embed?pb=!1m18!4m12!3m6!1m3!1d3022.215!2d$lng!3d$lat!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!5e0!3m2!1s$language!2s$country!4v" . time())
Iframe Sandboxing:
GOOGLE_MAPS_EMBED_API_KEY=your_key?libraries=places&callback=initMap
Filament Version Compatibility:
composer.json:
"codewithdennis/filament-simple-map": "^1.0"
Inspect the Embed URL:
Open browser dev tools (F12) and check the src attribute of the iframe to verify the URL is correct.
Check API Key Usage: Monitor your Google Cloud Console for API key errors or quota limits.
Disable JavaScript Errors: Temporarily disable JavaScript in your browser to isolate if the issue is client-side:
MapAction::make('map')->extraAttributes(['data-disable-js-check' => true])
Log Coordinates: Debug coordinate values by logging them in the action:
MapAction::make('map')
->latitude(fn ($record) => (log($record->latitude), $record->latitude))
->longitude(fn ($record) => (log($record->longitude), $record->longitude))
Custom Map Providers: Extend the action to support non-Google maps (e.g., OpenStreetMap):
MapAction::make('map')
->mapUrl(fn ($lat, $lng) => "https://www.openstreetmap.org/?mlat=$lat&mlon=$lng#map=12/$lat/$lng")
Add Markers:
Use the extraAttributes method to pass custom JavaScript for markers:
MapAction::make('map')
->extraAttributes([
'data-markers' => json_encode([
['lat' => $lat, 'lng' => $lng, 'title' => 'Location']
]),
])
Then override the default iframe template to include marker logic.
Dynamic Zoom Levels: Adjust zoom based on data (e.g., zoom out for broader regions):
MapAction::make('map')
->zoom(fn ($record) => $record->is_global ? 2 : 12)
Local Storage:
Persist map state (e.g., user-selected locations) using localStorage:
MapAction::make('map')
->extraAttributes([
'data-save-to-localstorage' => true,
'data-storage-key' => 'user_map_prefs',
])
Accessibility: Add ARIA labels and keyboard navigation support by extending the Blade template:
MapAction::make
How can I help you explore Laravel packages today?