NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

The facade is the recommended default, not the only way in. There are three equivalent entry points:

  • The Geolocation facade — the shortest form.
  • The manager, RoundlyConsulting\Geolocation\GeolocationManager — the facade root, a container singleton (also aliased as geolocation). Inject it through the constructor for the same API as an explicit dependency, with no static calls.
  • Actions — single-purpose classes with execute(), for composing into your own jobs and commands. Here there is exactly one.

Injecting the manager

use Illuminate\Http\Request;
use RoundlyConsulting\Geolocation\GeolocationManager;

final class CheckoutController
{
    public function __construct(private GeolocationManager $geolocation) {}

    public function __invoke(Request $request)
    {
        $location = $this->geolocation->locateRequest($request);

        $distance = $location === null
            ? null
            : $this->geolocation->distanceBetween($this->warehouse(), $location->coordinates());
        // ...
    }
}

Geolocation::fake() replaces the facade root and the container binding, so an injected manager — and $request->location() — is faked too.

The one action

The only state-changing use case, refreshing the MaxMind database, is also an action you can resolve directly — for example from your own scheduled job:

use RoundlyConsulting\Geolocation\Actions\UpdateDatabaseAction;

$path = app(UpdateDatabaseAction::class)->execute(edition: 'GeoLite2-City');
ActionFacade method
UpdateDatabaseActionupdateDatabase(?$edition, ?$path)

Lookups and distances have no action classes: they run through the provider pipeline, and each provider is a remote-API client you can swap in the providers map (see Custom providers). Calling the action directly skips the manager, so Geolocation::fake() does not record it — use updateDatabase() when a test should see the refresh.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.