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

Search & find place

Three ways to discover places, all returning Place objects:

use RoundlyConsulting\GooglePlaces\DataTransferObjects\Location;
use RoundlyConsulting\GooglePlaces\DataTransferObjects\NearbySearchQuery;
use RoundlyConsulting\GooglePlaces\DataTransferObjects\TextSearchQuery;
use RoundlyConsulting\GooglePlaces\Facades\GooglePlaces;

// Text search → Collection<Place>
$places = GooglePlaces::textSearch('pizza in Bratislava');

$places = GooglePlaces::textSearch(
    (new TextSearchQuery('vegan brunch'))->openNow()->withMinRating(4.0)->take(10),
);

// Nearby search → Collection<Place> (radius 0–50000 m)
$places = GooglePlaces::nearbySearch(
    (new NearbySearchQuery(new Location(48.1486, 17.1077), radius: 1500))
        ->withinTypes('cafe')
        ->rankBy('DISTANCE'),
);

// Find a single best match → ?Place
$place = GooglePlaces::findPlace('Eiffel Tower');

findPlace() runs a one-result text search. Pass a Location as the second argument to bias the match toward a 5 km circle around it:

// Bias the match toward a point (a 5 km circle around it):
$place = GooglePlaces::findPlace('Old Town Hall', new Location(48.1486, 17.1077));

Text search options

$query = (new TextSearchQuery('pizza'))
    ->inLanguage('sk')
    ->inRegion('sk')
    ->ofType('restaurant')       // a single included type
    ->openNow()
    ->withMinRating(4.0)
    ->take(20);                  // page size

$places = GooglePlaces::textSearch($query);
MethodEffect
withText(string $text)Replace the search text.
inLanguage(string $language)Response language (default en).
inRegion(string $region)Region code.
take(int $pageSize)Page size.
ofType(string $type)A single included place type.
openNow(bool $openNow = true)Only places open now.
withMinRating(float $rating)Minimum average rating.
withPriceLevels(string ...$levels)Google price levels, passed through as-is.
preferInArea() / restrictTo()Location bias / restriction (LocationDefinition).
nearby() / withinBounds()Circle bias / rectangle restriction shortcuts.
rankBy(string $preference)Google rank preference, passed through as-is.
withPageToken(string $token)Fetch a specific page.

Nearby search options

$query = (new NearbySearchQuery(new Location(48.1486, 17.1077), radius: 1500))
    ->withinTypes('cafe', 'bakery')
    ->excludingTypes('restaurant')
    ->take(10)                   // max result count
    ->inLanguage('sk');

$places = GooglePlaces::nearbySearch($query);
MethodEffect
new NearbySearchQuery(Location $location, int $radius = 5000)Centre and radius in metres (0–50000, otherwise a PlacesException).
withRadius(int $radius)Change the radius.
withinTypes(string ...$types)Included place types.
excludingTypes(string ...$types)Excluded place types.
take(int $max)Maximum result count.
rankBy(string $preference)Google rank preference, e.g. DISTANCE.
inLanguage(string $language)Response language (default en).

Location-bias helpers

Bias or restrict text search fluently:

use RoundlyConsulting\GooglePlaces\DataTransferObjects\Location;
use RoundlyConsulting\GooglePlaces\DataTransferObjects\TextSearchQuery;

(new TextSearchQuery('coffee'))->nearby(48.1486, 17.1077, radius: 2000);              // circle bias
(new TextSearchQuery('coffee'))->withinBounds(new Location(48.1, 17.0), new Location(48.2, 17.2)); // rectangle restriction

Pagination

Text search caps at 60 results; pass a page token to walk a single page manually:

$next = GooglePlaces::textSearch((new TextSearchQuery('pizza'))->withPageToken($token));

Or let the package follow nextPageToken for you. all() eagerly collects every page; cursor() returns a LazyCollection that fetches pages on demand; pages() yields one collection per page. All three honour the pagination.max_pages safety cap (default 5) — when it is hit with more pages available, paging stops and a warning is logged:

use RoundlyConsulting\GooglePlaces\DataTransferObjects\Place;
use RoundlyConsulting\GooglePlaces\Facades\GooglePlaces;

// Eagerly collect every page into one collection:
$all = GooglePlaces::textSearchPaginated('museums in Bratislava')->all();

// Stream lazily — only fetches the next page when you ask for more places:
GooglePlaces::textSearchPaginated('museums')
    ->cursor()
    ->each(function (Place $place): void {
        // ...
    });

// Stop early — pages beyond the first 25 places are never requested:
$first = GooglePlaces::textSearchPaginated('museums')->cursor()->take(25)->collect();

// Page by page — each item is a Collection<Place>:
foreach (GooglePlaces::textSearchPaginated('museums')->pages() as $page) {
    // one billed request per page
}

// Nearby search returns a single page (the New API does not paginate it):
$all = GooglePlaces::nearbySearchPaginated($nearbyQuery)->all();

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.