tipoff/laravel-serpapi
Laravel wrapper for SerpApi that simplifies running Google and other search engine queries from your app. Provides configuration, service bindings, and a clean API to fetch SERP results for SEO tools, monitoring, and data extraction.
Installation
composer require tipoff/laravel-serpapi
Publish the config file:
php artisan vendor:publish --provider="Tipoff\SerpApi\SerpApiServiceProvider"
Configuration
Edit .env and add:
SERPAPI_KEY=your_api_key_here
Verify the config in config/serpapi.php.
First Use Case Fetch a Google search result in a controller:
use Tipoff\SerpApi\SerpApi;
public function search()
{
$results = SerpApi::search('laravel serpapi', 'google');
return response()->json($results);
}
Search Queries Use the facade for common search types:
// Google search
$google = SerpApi::search('laravel', 'google');
// YouTube search
$youtube = SerpApi::search('laravel tutorial', 'youtube');
// Custom engine
$custom = SerpApi::search('query', 'custom_engine', ['param' => 'value']);
Result Processing Extract structured data from responses:
$results = SerpApi::search('laravel jobs', 'google');
$organicResults = collect($results['organic_results'] ?? []);
Rate Limiting & Retries Handle API limits gracefully:
try {
$data = SerpApi::search('query', 'google', [], 3); // Retry 3 times
} catch (\Tipoff\SerpApi\Exceptions\RateLimitException $e) {
// Log or queue for later
}
SearchJob::dispatch('query')->delay(now()->addMinutes(1));
$results = Cache::remember("serpapi_{$query}", now()->addHours(1), function() use ($query) {
return SerpApi::search($query, 'google');
});
config(['serpapi.key' => DB::table('api_keys')->where('active', 1)->value('key')]);
Deprecated Methods The package is outdated (last release 2021). Check SerpAPI’s official docs for breaking changes in their API.
$client = new \GuzzleHttp\Client();
$response = $client->get('https://serpapi.com/search', [
'query' => [
'q' => 'laravel',
'api_key' => config('serpapi.key'),
]
]);
Missing Error Handling The package lacks granular exception handling for different HTTP statuses.
try {
$results = SerpApi::search('query', 'google');
} catch (\Tipoff\SerpApi\Exceptions\SerpApiException $e) {
if ($e->getCode() === 429) {
// Rate limited
}
if ($e->getCode() === 401) {
// Invalid API key
}
}
Config Overrides
The config/serpapi.php may not support all SerpAPI parameters. Extend the config:
'engines' => [
'google' => [
'params' => [
'hl' => 'en', // Default language
'gl' => 'us', // Default country
],
],
],
Log Raw Responses Add a middleware to log responses for debugging:
public function handle($request, Closure $next)
{
$response = $next($request);
if ($request->routeIs('serpapi.*')) {
\Log::debug('SerpAPI Response:', [
'data' => $response->getData(),
'status' => $response->getStatusCode(),
]);
}
return $response;
}
Validate API Key Test the key manually first:
curl "https://serpapi.com/search.json?q=test&api_key=YOUR_KEY"
Custom Engines
Add support for unsupported engines by extending the SerpApi facade:
// app/Providers/SerpApiServiceProvider.php
public function boot()
{
SerpApi::extend('bing', function ($query, $params = []) {
return $this->call('bing', $query, $params);
});
}
Response Transformers Create a transformer to normalize responses:
class GoogleSearchTransformer
{
public static function transform($data)
{
return collect($data['organic_results'] ?? [])
->map(fn($result) => [
'title' => $result['title'],
'url' => $result['link'],
'snippet' => $result['snippet'],
]);
}
}
Mocking for Tests Use a mock HTTP client in tests:
$this->mock(SerpApi::class)->shouldReceive('search')
->once()
->andReturn(['organic_results' => []]);
How can I help you explore Laravel packages today?