Website Screenshot API
for PHP
PHP doesn't have a built-in way to render web pages. To capture website screenshots, you either run a headless browser on your server or call an external API. Here are working examples for both approaches.
1. GrabShot API with cURL
The simplest way. No browser to install, no dependencies beyond PHP's built-in cURL extension. One function, works on any PHP hosting.
<?php
function screenshot(string $url, string $output = 'screenshot.webp'): void
{
$apiKey = 'YOUR_API_KEY'; // Free at grabshot.dev
$params = http_build_query([
'url' => $url,
'format' => 'webp',
'width' => '1440',
'apiKey' => $apiKey,
]);
$ch = curl_init("https://grabshot.dev/v1/screenshot?{$params}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$image = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new RuntimeException("Screenshot failed: HTTP {$httpCode}");
}
file_put_contents($output, $image);
echo "Saved " . strlen($image) . " bytes to {$output}\n";
}
screenshot('https://github.com');
Works on: Any PHP 7.4+ hosting, shared hosting, VPS, Laravel Forge, Docker. No Chrome needed.
2. GrabShot with Guzzle (Laravel / Symfony)
If you're using a framework, Guzzle is likely already in your project.
composer require guzzlehttp/guzzle
<?php
use GuzzleHttp\Client;
function screenshot(string $url, string $output = 'screenshot.webp'): void
{
$client = new Client(['timeout' => 30]);
$response = $client->get('https://grabshot.dev/v1/screenshot', [
'query' => [
'url' => $url,
'format' => 'webp',
'width' => '1440',
'apiKey' => env('GRABSHOT_API_KEY'), // .env file
],
]);
file_put_contents($output, $response->getBody());
}
// In a Laravel controller:
public function captureScreenshot(Request $request)
{
$url = $request->validate(['url' => 'required|url'])['url'];
$client = new Client(['timeout' => 30]);
$response = $client->get('https://grabshot.dev/v1/screenshot', [
'query' => [
'url' => $url,
'format' => 'png',
'width' => '1440',
'deviceFrame' => 'macbook-air',
'aiCleanup' => 'true',
'apiKey' => config('services.grabshot.key'),
],
]);
return response($response->getBody())
->header('Content-Type', 'image/png')
->header('Content-Disposition', 'inline; filename="screenshot.png"');
}
3. Self-Hosted with chrome-php
If you need to interact with pages (fill forms, click buttons) or want full local control, chrome-php/chrome runs headless Chrome from PHP.
composer require chrome-php/chrome
<?php
use HeadlessChromium\BrowserFactory;
$browserFactory = new BrowserFactory('google-chrome');
$browser = $browserFactory->createBrowser([
'headless' => true,
'windowSize' => [1440, 900],
'noSandbox' => true,
'customFlags' => ['--disable-gpu'],
]);
try {
$page = $browser->createPage();
$page->navigate('https://github.com')->waitForNavigation();
$screenshot = $page->screenshot([
'format' => 'png',
'quality' => 90,
]);
$screenshot->saveToFile('github.png');
echo "Screenshot saved\n";
} finally {
$browser->close();
}
Pros: Full browser control, free, can interact with pages.
Cons: Needs Chrome installed on server (not available on shared hosting). Uses 300-500MB RAM. Requires proc_open which many hosts disable.
WordPress Integration
Using GrabShot with WordPress (no plugin needed):
<?php
// In your theme's functions.php or a custom plugin
function grabshot_screenshot(string $url): string|false
{
$api_key = get_option('grabshot_api_key');
$response = wp_remote_get(
add_query_arg([
'url' => $url,
'format' => 'webp',
'width' => '1200',
'apiKey' => $api_key,
], 'https://grabshot.dev/v1/screenshot'),
['timeout' => 30]
);
if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) {
return false;
}
// Save to uploads directory
$upload_dir = wp_upload_dir();
$filename = 'screenshot-' . md5($url) . '.webp';
$filepath = $upload_dir['path'] . '/' . $filename;
file_put_contents($filepath, wp_remote_retrieve_body($response));
return $upload_dir['url'] . '/' . $filename;
}
// Usage in a template:
$screenshot_url = grabshot_screenshot('https://example.com');
if ($screenshot_url) {
echo '<img src="' . esc_url($screenshot_url) . '" alt="Screenshot">';
}
Comparison
| Feature | GrabShot API | chrome-php |
|---|---|---|
| Works on shared hosting | Yes | No |
| Needs Chrome installed | No | Yes |
| RAM usage | Minimal | 300-500MB |
| Device frame mockups | Built-in | No |
| AI popup removal | Yes | Manual scripting |
| Page interaction | No | Full |
| Cost | Free tier, then $9/mo | Server costs |
See it in action
Try GrabShot right now — paste any URL and get a screenshot instantly. No signup needed.
Try Free Screenshot Tool →