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

Filament Google Map Location Picker Laravel Package

yemenpoint/filament-google-map-location-picker

A Filament form field for picking locations on Google Maps. Search or drag a marker to capture latitude and longitude, with optional address details saved to your model. Quick setup for Laravel Filament apps and location-based forms.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a small, single-purpose Filament form component: it drops a Google Map into a form, lets the user click/drag a marker, and writes the chosen coordinates back to your model. Treat it as a coordinate picker, not a full mapping suite (no polygons, no multi-marker, no clustering).

Minimal steps:

composer require yemenpoint/filament-google-map-location-picker
php artisan vendor:publish --tag="filament-google-map-location-picker-config" # if the tag exists
  1. Enable the Maps JavaScript API in Google Cloud Console and create an API key. Billing must be enabled even for the free tier.
  2. Put the key in .env:
    GOOGLE_MAPS_API_KEY=AIza...
    
    and clear the config cache (php artisan config:clear) — the key is read server-side and handed to the Livewire/Alpine component.
  3. Use the component inside any Filament form schema. Verify the exact namespace against src/Forms/Components/ in the repo, but the shape is:
    use Yemenpoint\FilamentGoogleMapLocationPicker\Forms\Components\GoogleMapLocationPicker;
    
    GoogleMapLocationPicker::make('location')
        ->label('Store location');
    

Where to look first: the README for the exact class name and setter methods (the package predates Filament v3 conventions and the docs are thin), then src/ for the Alpine view and config file. The config file is where the API key and default map center/zoom live.

First use case: a StoreResource create/edit form where an admin pins the shop on a map. Store the result in latitude / longitude decimal columns, and render a read-only "View on map" link in the table.

Implementation Patterns

Two-column storage (most common). Keep latitude and longitude as separate decimal(10,7) columns. Cast them in the model and let the field populate both:

// migration
$table->decimal('latitude', 10, 7)->nullable();
$table->decimal('longitude', 10, 7)->nullable();

If the component writes to a single JSON column, hydrate/dehydrate manually in the form — check the source before committing to a schema.

Edit hydration. The biggest day-to-day friction is re-opening an edit form and finding the map centered on the default city instead of the saved pin. Pass the existing values explicitly:

GoogleMapLocationPicker::make('location')
    ->default(fn ($record) => $record
        ? ['lat' => $record->latitude, 'lng' => $record->longitude]
        : null)

If the package supports it, prefer the native defaultLocation() / defaultZoom() setters over ->default(), since the field's internal state shape is package-specific.

Reverse geocoding into an address field. Pair the picker with a text input and resolve the address on save (or on change via ->live() + afterStateUpdated). Doing it server-side in the resource's mutateFormDataBeforeSave() keeps the API key's server-side geocoding calls separate from the browser key:

protected function mutateFormDataBeforeSave(array $data): array
{
    $data['address'] ??= app(Geocoder::class)
        ->reverse($data['latitude'], $data['longitude']);
    return $data;
}

Reusable schema. Wrap the field in a LocationPickerSchema::make() static method or a HasLocation trait so every resource that needs a pin gets identical config (zoom, restrictions, required validation).

Validation. The picker gives you coordinates, not correctness. Add bounds validation:

->rules(['required', 'numeric', 'between:-90,90']) // per field if split

Table display. Don't embed a map per row — it's slow and burns API quota. Render a link instead:

Tables\Columns\TextColumn::make('latitude')
    ->formatStateUsing(fn ($record) => $record->latitude
        ? "{$record->latitude}, {$record->longitude}"
        : '—')
    ->url(fn ($record) => $record->latitude
        ? "https://maps.google.com/?q={$record->latitude},{$record->longitude}"
        : null, true);

Gotchas and Tips

  • Version compatibility is the #1 risk. Last release was 2022-11-05, which puts it firmly in the Filament v2 era. If you're on Filament v3/v4, expect namespace and Forms\Components API mismatches. Pin the version, test in a branch, and budget time to fork. With 0 dependents and 29 stars, upstream fixes are unlikely.
  • The API key is client-side. The browser key is visible in the DOM/network tab. In Cloud Console, restrict it by HTTP referrer to your admin domain(s) and by API (Maps JavaScript only). Keep server-side geocoding on a separate, IP-restricted key.
  • Config cache bites everyone. After changing GOOGLE_MAPS_API_KEY in .env, run php artisan config:clear (or optimize:clear). A stale cached config silently renders a blank/grey map.
  • Livewire + modals. Maps initialized inside Filament modals often fail because the container has zero height at init. Check the package's Alpine init hook; if it's missing a Livewire.hook('message.processed') re-init, the map shows grey until you resize the window. Fix by ensuring a fixed height on the container via the field's ->extraAttributes() or a small CSS override.
  • Blank map debugging order: (1) browser console for ApiNotActivatedMapError / RefererNotAllowedMapError, (2) API key present in the rendered HTML, (3) Maps JS API enabled + billing on, (4) container height, (5) config cache.
  • Nulls and partial state. Clicking the map then submitting without moving the marker can leave one coordinate set and the other null depending on how state is split. Guard with a required_with rule or a saving observer that nulls both if either is missing.
  • Extension points are limited. The realistic ones are: publish and edit the Blade/Alpine view, subclass the component to override its setters, and wrap it in your own schema class. There's no event system or multi-marker support.
  • Mobile dragging. Draggable markers on touch devices are finicky; set ->draggable(true) only if the underlying Google Maps config supports it, and consider a "use my location" button backed by the browser Geolocation API as a fallback.
  • If it fights you, swap it. For anything beyond a single pin, cheesegrits/filament-google-maps is the actively maintained, feature-rich alternative (multi-marker, clustering, geocoding, draw tools). This package is worth it only for a tiny single-pin admin form where you're already pinned to its Filament version.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource