spatie/googlesearch
Fetch search results from a paid Google Custom Search Engine in PHP/Laravel. Includes service provider, facade, and configurable API key/CSE ID setup to return results as an array for easy integration into your app.
Installation:
composer require spatie/googlesearch
Add to config/services.php (if not present):
'google-search' => [
'engine_id' => env('GOOGLE_SEARCH_ENGINE_ID'),
'api_key' => env('GOOGLE_API_KEY'),
],
Environment Variables:
GOOGLE_SEARCH_ENGINE_ID=your_custom_search_engine_id
GOOGLE_API_KEY=your_api_key
First Query:
use Spatie\GoogleSearch\GoogleSearch;
$results = GoogleSearch::search('laravel best practices');
// Returns array of results with metadata (title, link, snippet, etc.)
// Fetch top 5 results for a query
$results = GoogleSearch::search('laravel 10 features', 5);
// Access a specific result
$firstResult = $results[0];
echo $firstResult['title']; // Outputs the title of the first result
// Search with start index (pagination)
$results = GoogleSearch::search('laravel testing', 10, 1); // 10 results, starting at index 1
// Search with custom parameters (e.g., date range)
$results = GoogleSearch::search('laravel news', 5, 1, [
'cr' => 'countryUS', // Restrict to US
'tbs' => 'qdr:m', // Last month
]);
Service Provider Binding:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(GoogleSearch::class, function ($app) {
return new GoogleSearch(
config('services.google-search.engine_id'),
config('services.google-search.api_key')
);
});
}
Usage in Controllers:
public function search(Request $request)
{
$query = $request->input('q', 'default query');
$results = app(GoogleSearch::class)->search($query);
return view('search.results', compact('results'));
}
// Cache results for 1 hour
$results = Cache::remember("google_{$query}", 3600, function () use ($query) {
return GoogleSearch::search($query);
});
// Process multiple queries in a loop
$queries = ['laravel', 'php', 'symfony'];
foreach ($queries as $query) {
$results = GoogleSearch::search($query);
// Store or process results
}
Pitfall: Forgetting to set up a Google Custom Search Engine (CSE) before using the package.
Pitfall: Hardcoding API keys or engine IDs in code.
.env and Laravel’s config/services.php.try-catch to handle Google_Service_Exception for quota errors.try {
$results = GoogleSearch::search('query');
} catch (\Google_Service_Exception $e) {
Log::error('Google Search API quota exceeded: ' . $e->getMessage());
return back()->with('error', 'Search service unavailable.');
}
$safeTitle = htmlspecialchars($result['title']);
snippet or link).
isset() or data_get() to safely access nested keys:
$snippet = data_get($result, 'snippet', 'No snippet available.');
GoogleSearch::setLogger(function ($message) {
Log::debug('Google Search API:', ['message' => $message]);
});
storage/logs/laravel.log for Google_Service_Exception errors.// app/Services/GoogleSearchService.php
class GoogleSearchService
{
public function searchWithFallback($query)
{
try {
return GoogleSearch::search($query);
} catch (\Exception $e) {
return $this->fallbackToLocalDatabase($query);
}
}
}
google/apiclient).matthecat/laravel-google-search (if available).How can I help you explore Laravel packages today?