> ## Documentation Index
> Fetch the complete documentation index at: https://flex-fields.bjanczak.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Examples target Filament 5. Verify optional dependencies before configuring integrations.
> Upload transfer completion, permanent storage and record acceptance are separate milestones. Native and Spatie image conversions retain the original.

# MapMarkersField

> Add, move and cluster multiple locations, stored as a validated GeoJSON Point collection.

<video autoPlay muted loop playsInline controls preload="metadata" src="https://mintcdn.com/flex-fields/cY70dYD2SDr8chb8/art/previews/map-markers-motion.mp4?fit=max&auto=format&n=cY70dYD2SDr8chb8&q=85&s=954ff9072cc28894eeda978eb179bafe" poster="/art/previews/map-markers.webp" width="1920" height="1080" aria-label="MapMarkersField — FLEX Fields demonstration">
  [Watch the MapMarkersField demonstration (MP4).](https://flex-fields.bjanczak.com/art/previews/map-markers-motion.mp4)
</video>

`MapMarkersField` collects several locations in one field. Use it for delivery stops, branches, equipment positions or other sets of points. It enables marker collection mode automatically.

## Basic usage

```php theme={"theme":{"light":"github-light","dark":"github-dark"}}
use Bjanczak\FilamentFlexFields\Filament\Forms\Components\MapMarkersField;

MapMarkersField::make('stops')
    ->label('Delivery stops')
    ->mapProvider('maplibre')
    ->searchable(false)
    ->draggableMarkers()
    ->minFeatures(1)
    ->maxFeatures(50)
    ->clusterMarkers()
    ->fitFeatures()
    ->mapHeight(420)
    ->fullscreen()
    ->required();
```

This example adds points through the map without a geocoder. To enable address search, use `searchable()` and configure your [search provider and authenticated endpoints](https://flex-fields.bjanczak.com/docs/location-v4.md#shared-address-search-endpoints). Selecting a search result adds a marker to the collection.

## State and database storage

Use a JSON column with an Eloquent `array` cast for `stops`. Each marker is a GeoJSON Point with a stable feature ID:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "id": "stop-1",
      "geometry": {"type": "Point", "coordinates": [21.0122, 52.2297]},
      "properties": {"label": "Warehouse", "color": "#3b82f6"}
    }
  ]
}
```

Coordinates are `[longitude, latitude]`. Existing collections hydrate through the form; setting a camera center alone does not add a marker. Marker mode requires structured storage, not `storeFormat('string')`.

## Adding, moving and removing markers

Clicking the map adds a point when `selectOnMapClick()` is enabled. Select a marker to drag it. Use `manualCoordinates()` for coordinate entry and `geolocation()` for optional device location after a permission request initiated by the user.

`draggableMarkers(false)` disables marker dragging. `deletableFeatures(false)` prevents feature removal; `readOnly()` or a disabled field blocks edits. Undo and redo apply to committed edits; drag previews do not become separate history entries.

## Clustering and list layout

```php theme={"theme":{"light":"github-light","dark":"github-dark"}}
MapMarkersField::make('stops')
    ->mapProvider('maplibre')
    ->searchable(false)
    ->clusterMarkers()
    ->clusterRadius(50)
    ->clusterMaxZoom(12)
    ->clusterMinimumPoints(3)
    ->maxFeatures(100)
    ->featureListMaxHeight(320);
```

Clusters show counts and expand on click. `clusterRadius()` accepts 20–100 pixels; the maximum cluster zoom must be below `maxZoom()`. Unselected points use GPU-rendered circles, with one selected DOM drag target per map instance.

Feature lists grow naturally unless `featureListMaxHeight()` bounds their scroll area. This setting accepts 128–4096 pixels; `null` restores natural height.

## Validation and custom actions

The server validates feature IDs, Point coordinates, allowed area policies and the configured feature-count limits. `maxFeatures()` can be configured up to the hard limit of 200 features. Labels and other admitted properties are validated independently of browser edits.

Use `featureSchema()` to edit custom marker data in a native Filament modal. `featureActions()` and `afterFeatureAdded()`, `afterFeatureUpdated()` and `afterFeatureDeleted()` connect accepted changes to your PHP code. See [feature forms, actions and events](https://flex-fields.bjanczak.com/docs/map-feature-forms.md) for complete examples and persistence rules.

## Related components

* [MapPickerField](https://flex-fields.bjanczak.com/docs/mappickerfield.md) — one address/location.
* [MapCoordinatesField](https://flex-fields.bjanczak.com/docs/map-coordinates.md) — one coordinate pair without geocoding.
* [MapEditorField](https://flex-fields.bjanczak.com/docs/map-editor.md) — points, lines and polygons in one collection.
* [Shared map configuration](https://flex-fields.bjanczak.com/docs/location-v4.md) — providers, appearance and controls.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.