---
url: /modules/locator.md
---
# Locator

Locations with address, coordinates and region, a store finder block that searches them, and a map block for a single address. Addresses are geocoded through Google when a location is saved.

::: glance

* **Module key** `locator`
* **Default** on
* **Switch** `EVOLVE_MODULE_LOCATOR`, see [Modules](/modules/#switching-a-module-on-or-off)
* **Role access** `evolve.roles.modules.locator`
* **Panel** `/evolve/locator/location`, `/evolve/locator/region`
  :::

## Requirements

Two Google keys from the project's Google Cloud project, both in `.env`:

| Variable | Used for |
|---|---|
| `GOOGLE_GEOCODING_API_KEY` | turning a location's address into coordinates when it is saved (Geocoding API) |
| `GOOGLE_MAPS_API_KEY` | rendering maps on the site (Maps JavaScript API) |

The package ships no keys . Earlier versions carried Racerfish fallback keys as config defaults; those keys are rotated. A site that relied on them sets its own before updating, otherwise map and zip search stop with the update and only the health check says why. Restrict the keys in the Google Cloud console to the site's domains.

Without `GOOGLE_GEOCODING_API_KEY` saving a location leaves latitude and longitude empty and the log notes the skipped geocoding. Without `GOOGLE_MAPS_API_KEY` the store finder lists and filters without the map and the map block renders its empty frame. Nothing fails, but the [API keys health check](/site/health-checks#api-keys) names the missing key while the module is on.

## Configuration

`config/locator.php` has no `.env` keys. `allow-blocks` (block editor on locations) and `allow-routeable` are both `false`. With `allow-routeable` on, the module exposes `api/locator/location` and `api/locator/region` for a custom frontend; the shipped store finder block does not need them.

## In the panel

* **Locations** at `/evolve/locator/location`: name, address, contact details, region, opening hours and the coordinates the geocoder found. Saving an address geocodes it; the geocoder rejects empty or overlong input and times out after five seconds.
* **Regions** at `/evolve/locator/region`: groups of locations used as a filter.
* Cmd-K: "Locations", "Regions", "New location". Locations are in the global search.

## On the site

| Block | Component | Fields |
|---|---|---|
| Standort-Finder | `locator.locations` | title, intro text. A Livewire search over all locations with distance and region filter. |
| Karte | `locator.map` | pin link, address, zoom level, a map style as JSON. One address on a map. |

Both blocks render from the module. CMS-editable fields in the store finder are escaped before output (fixed in 2.5).

## Publishing

`locator.config` publishes `config/locator.php`. `locator.components` publishes the block definitions, the `Map.php` blueprint to `app/Blueprints`, frontend views to `theme/views/vendor/locator/frontend` and the block views to `theme/views/components/blocks/locator`.

## Verifying

Save a location with a full address and check that latitude and longitude are filled. If they stay empty, the geocoding key is missing, restricted to the wrong API, or the Geocoding API is not enabled in the Google project. Geocoding results are cached, so correct the key and save the location again.
