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

The Geolocation facade

The Geolocation facade is the recommended entry point. It is registered automatically (global alias Geolocation) and resolves GeolocationManager, so every call below also works on an injected manager — see DI and actions. The full surface:

use RoundlyConsulting\Geolocation\DataTransferObjects\Coordinates;
use RoundlyConsulting\Geolocation\DataTransferObjects\DistanceQuery;
use RoundlyConsulting\Geolocation\DataTransferObjects\GeolocationQuery;
use RoundlyConsulting\Geolocation\Enum\DistanceType;
use RoundlyConsulting\Geolocation\Facades\Geolocation;

// Locate
Geolocation::locateIp('8.8.8.8');                  // ?Location
Geolocation::locateRequest();                      // the client IP of the current request
Geolocation::locateAddress('1600 Amphitheatre Pkwy, Mountain View');
Geolocation::locateCoordinates(new Coordinates(48.1486, 17.1077));
Geolocation::locate(GeolocationQuery::forIp('8.8.8.8'));
Geolocation::batch(['8.8.8.8', '1.1.1.1']);        // array<string, ?Location>

// Measure
Geolocation::distanceBetween($from, $to);          // ?Distance — driving by default
Geolocation::distance(DistanceQuery::between($from, $to, DistanceType::Walking));
Geolocation::distanceMatrix([$warehouse], [$a, $b]);   // DistanceMatrix

// Scoped copies — they apply to the call they are chained to, nothing else
Geolocation::provider('ipinfo')->locateIp('8.8.8.8');
Geolocation::using('maxmind_database', 'ipinfo')->locateIp('8.8.8.8');
Geolocation::withToken('ipinfo', 'runtime-token')->locateIp('8.8.8.8');
Geolocation::withTimeout(10)->locateIp('8.8.8.8');

// Maintain
Geolocation::updateDatabase();                     // refresh the MaxMind .mmdb, returns the path
Geolocation::forget(GeolocationQuery::forIp('8.8.8.8'));   // drop one cached result
Geolocation::flushCache();                         // drop every cached lookup and distance
Geolocation::extend('my_provider', fn () => new MyProvider());

Method reference

MethodReturnsPurpose
locateIp($ip) / locateAddress($address)?LocationResolve an IP or a street address.
locateCoordinates($coordinates)?LocationReverse-geocode a Coordinates value.
locateRequest(?$request)?LocationThe client IP of the current (or given) request; null without an IP.
locate($query)?LocationResolve any GeolocationQuery.
batch($ips)array<string, ?Location>Many IPs at once; failures become null per item.
distance($query)?DistanceTravel distance for a DistanceQuery.
distanceBetween($from, $to, $type)?Distancedistance() without building the query; Driving by default.
distanceMatrix($origins, $destinations, $type)DistanceMatrixAn origin × destination grid in one call.
updateDatabase(?$edition, ?$path)stringDownload or refresh the MaxMind .mmdb; returns the written path.
forget($query)boolDrop one cached lookup or distance.
flushCache()voidInvalidate every cached lookup and distance.
provider($name) / using(...$names)GeolocationManagerA scoped copy that consults only the named providers.
withToken($provider, $token)GeolocationManagerA scoped copy that sends this token or key to the named provider only.
withConfig($provider, $overrides)GeolocationManagerA scoped copy with config overrides for the named provider only.
withTimeout($seconds)GeolocationManagerA scoped copy with this HTTP timeout for every provider.
extend($name, $factory)GeolocationManagerRegister a closure provider for the pipeline.
fake(array $results = [])GeolocationFakeSwap in the recording fake — see Testing.

locate(), distance() and distanceBetween() return null when no provider can resolve the query, including when every provider is unreachable. provider(), using() and the with*() overrides return a scoped copy of the manager: it lasts exactly as long as the call chain it is attached to, and the shared manager never changes. GeolocationManager is also Macroable — see Per-call options.

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.