Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
For the shortest PHP implementation, use a hosted screenshot API. Your application sends a URL and receives image bytes or a render URL, while the provider runs the browser. Choose a local package such as Spatie Browsershot when you need to control Chromium, inject your own scripts and CSS, or keep rendering inside your infrastructure. This guide shows both approaches, including full-page captures, waits, authentication, deployment, security, and failure recovery.
Choose a rendering approach
| Approach | What you operate | Best fit | Trade-off |
|---|---|---|---|
| ScreenshotNeo | HTTPS request; provider operates rendering browsers | Clean production captures, API automation, AI-agent workflows | Provider limits and credentials apply |
| Other hosted APIs (ScreenshotOne or Urlbox) | PHP SDK or HTTPS integration | Quick integration with vendor-specific options | Features, quotas and terms differ by provider |
| Spatie Browsershot | Composer, Node.js, Puppeteer and headless Chrome | Self-hosting and direct browser control | You maintain browser installation, updates, scaling and isolation |
Hosted services remove browser provisioning. Local Browsershot gives you Puppeteer-backed controls such as custom scripts, CSS, selectors and browser state, but every deployment must have a compatible Chrome and Node runtime.
Hosted PHP APIs
ScreenshotNeo: the recommended API
ScreenshotNeo is a website screenshot API and MCP server. It accepts a URL and returns PNG, JPEG, WebP or PDF. Before capture it can accept cookie-consent banners and remove more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be disabled. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Its 63 options include full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or custom viewports, retina scale, PDF paper and page controls, HTML/CSS rendering, custom JavaScript and CSS, clicks, selector/delay/network-idle waits, ad and request blocking, headers, cookies, user-agent and Authorization, timezone, geolocation, transparent backgrounds, resizing, configurable-TTL caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of 100 URLs per call, a usage API and an OpenAPI specification. Common parameter names used by other screenshot APIs also work.
Plans are Free (1,000 shots/month, no card), Starter ($5 for 3,000), Growth ($15 for 15,000), Pro ($39 for 60,000), Scale ($99 for 250,000) and Business ($249 for 1,000,000); annual billing provides two months free, and every feature is included on every plan.
#1 Best Overall
ScreenshotOne PHP SDK
ScreenshotOne documents installation with composer require screenshotone/sdk:^1.0. Construct a client with access and secret keys, then create TakeOptions::url("https://example.com"). Options can enable fullPage(true), a delay and geolocation. You can generate a signed take URL or download bytes and write them with file_put_contents. Its HTTPS API accepts GET or POST; access keys may be sent as GET parameters, in a JSON body or in an X-Access-Key header. Image responses use the requested MIME type, while errors are JSON containing a code and human-readable message. For large HTML or Markdown input, use a POST JSON body because query strings are smaller; one of URL, HTML or Markdown is required. See the provider’s current documentation before relying on quotas or plan terms.
Urlbox PHP package
Urlbox documents composer require urlbox/screenshots, Urlbox::fromCredentials('API_KEY', 'API_SECRET') and generateSignedUrl($options). The resulting URL can be placed directly in an <img> element. Urlbox describes direct render links plus synchronous and asynchronous JSON calls, with documented output categories including screenshots, PDFs, videos, text, HTML and metadata.
Minimal PHP request with a hosted API
The generic pattern is the same for any provider: validate the target URL, keep credentials server-side, send an HTTPS request, check the status and content type, then stream or store the bytes. The following example uses PHP’s cURL extension and a render endpoint; adapt parameter names to the service you choose.
<?php
$url = filter_input(INPUT_GET, 'url', FILTER_VALIDATE_URL);
if (!$url || !in_array(parse_url($url, PHP_URL_SCHEME), ['http', 'https'], true)) {
http_response_code(400);
exit('A valid HTTP(S) URL is required');
}
$ch = curl_init('https://provider.example/v1/screenshot');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 90,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $_ENV['SCREENSHOT_TOKEN']],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([
'url' => $url,
'format' => 'png',
'full_page' => true,
], JSON_THROW_ON_ERROR),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE) ?: '';
$error = curl_error($ch);
curl_close($ch);
if ($body === false || $status < 200 || $status >= 300 || !str_starts_with($type, 'image/')) {
http_response_code(502);
exit('Screenshot failed: ' . ($error ?: 'provider returned an error'));
}
header('Content-Type: ' . $type);
echo $body;
Do not let an untrusted visitor submit arbitrary internal addresses. Allow-list schemes and, for a multi-tenant service, resolve hostnames and block loopback, link-local, private and metadata-network ranges before submitting jobs.
Self-hosted capture with Spatie Browsershot
Install and configure
Browsershot passes a URL or HTML document to Puppeteer, which controls a headless version of Google Chrome. Install the PHP package with Composer, then install Puppeteer and configure its Node and Chrome paths according to the official setup documentation. The setup page also documents a Lambda deployment option.
Rank #2
composer require spatie/browsershot
npm install puppeteer
A minimal URL capture is:
<?php
use SpatieBrowsershotBrowsershot;
Browsershot::url('https://example.com')
->save(storage_path('app/example.png'));
Full page, viewport and element options
The image API documents PNG and JPEG output, viewport sizing, clipping, selecting one element, full-page mode, device scale, mobile emulation, delayed screenshots, selector waits, JavaScript and CSS injection, base64 output and returning an image directly to the browser.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstall<?php
use SpatieBrowsershotBrowsershot;
Browsershot::url('https://example.com/dashboard')
->windowSize(1440, 1000)
->deviceScaleFactor(2)
->fullPage()
->waitForSelector('.reports-ready')
->delay(750)
->setExtraHttpHeaders(['Authorization' => 'Bearer ' . $_ENV['DASHBOARD_TOKEN']])
->setCustomCss('.cookie-banner { display: none !important; }')
->save(storage_path('app/dashboard.png'));
Use Browsershot::html($html) for a supplied document. Treat that HTML as untrusted: isolate browser processes, restrict network access where possible and never expose a debugging port publicly.
Or skip the browser setup
With ScreenshotNeo, one GET request returns the rendered file. The example below writes a WebP response; see the ScreenshotNeo API documentation for all options and response headers.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
PHP
import requests; r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90); open("shot.webp", "wb").write(r.content)
The preceding snippet is Python, not PHP; for PHP use:
<?php
$query = http_build_query([
'access_key' => $_ENV['SCREENSHOTNEO_KEY'],
'url' => 'https://stripe.com',
]);
$image = file_get_contents('https://api.screenshotneo.com/v1/shot?' . $query);
if ($image === false) {
throw new RuntimeException('ScreenshotNeo request failed');
}
file_put_contents(__DIR__ . '/shot.webp', $image);
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' }); const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Cleanup removes cookie banners, popups and chat widgets before the shot. Bot checks, blank pages and failed loads are never billed. The MCP server lets AI agents take screenshots, and 1,000 screenshots per month are free with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.
Free tools Windows power users keep installed
One-click scans. No signup required.
Full-page captures, waits and dynamic content
Full-page behavior
“Full page” means the renderer expands the document beyond the initial viewport. Lazy-loaded images may still require scrolling or a provider’s lazy-image option. For local Chrome, verify that content appears after the page settles rather than assuming a fixed delay is sufficient.
Choose the right wait
- Selector wait: wait for a known application-ready element; this is usually more deterministic than sleeping.
- Delay: useful for animations or third-party widgets with no reliable selector.
- Network idle: useful for static data loading, but analytics or streaming connections can prevent it from completing.
Disable animations with custom CSS when a stable visual is more important than transition effects. Use a realistic viewport and device scale; changing either can alter responsive layout and text wrapping.
Authentication, private pages and PDFs
For protected pages, send cookies, custom headers or an Authorization header only through a trusted backend. Never place provider keys or session cookies in browser JavaScript. Hosted APIs may support these controls as options; with Browsershot, configure Puppeteer headers, cookies or a login sequence before capture. Remove sensitive values from logs and set short-lived credentials.
Use a PDF output when pagination, paper size, margins, landscape orientation or page ranges matter. A screenshot is a raster view and does not preserve selectable text or print layout. ScreenshotOne documents requested MIME types and Urlbox documents PDF output; ScreenshotNeo supports PDF controls including paper size, margins, landscape and page ranges.
Reliability, performance and cost decisions
- Cache deliberately: cache stable URLs and include a content or option version in your cache key. ScreenshotNeo lets you choose a cache TTL and identifies cache hits in response headers.
- Use asynchronous jobs: long pages and bulk work should not hold a PHP request open. ScreenshotNeo supports asynchronous jobs with signed webhooks and bulk capture for 100 URLs per call.
- Set timeouts: use an application timeout longer than the provider’s expected render time, but always bound retries. Retry transient transport failures, not invalid URLs or deterministic rendering errors.
- Control concurrency: local Chrome processes consume memory; queue jobs and cap workers. Hosted services shift that capacity management to the provider but still enforce account limits.
- Measure billing and outcomes: store HTTP status, content type, provider verdict and billing headers where available. Do not count a returned error document as an image.
Hosted pricing, quotas and availability can change, so confirm current provider terms before committing to a volume forecast. With self-hosting, your recurring cost is operational: Chrome updates, worker capacity, isolation and monitoring.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting checklist
Blank or partially rendered image
Wait for a meaningful selector, increase a bounded delay, enable full-page mode and verify that lazy content is loaded. Check whether the page requires JavaScript, authentication or a consent interaction.
Timeout or network-idle never completes
Replace network-idle with a selector wait or fixed delay. Streaming pages, analytics and long-polling requests commonly keep the network busy.
CAPTCHA, bot check or access denied
Do not attempt to bypass a CAPTCHA. Respect the site’s access rules, use an authorized session, or capture a page you control. ScreenshotNeo marks bot checks and CAPTCHAs as non-clean results and does not bill them.
Chrome or Puppeteer cannot start
Confirm Node.js, Puppeteer and Chrome are installed for the same runtime user, executable paths are configured, sandbox permissions match your container and shared memory is adequate. Capture stderr and test a simple public URL before debugging application code.
Wrong dimensions or clipped content
Set the viewport before navigation, use full-page mode for document height, or select an element explicitly. Check responsive breakpoints and device scale; a retina scale changes pixel dimensions without changing CSS layout.
Provider returns JSON instead of an image
Inspect HTTP status and Content-Type. JSON usually indicates an invalid option, missing credential, quota problem or render failure. Log the provider’s error code without logging secrets.
Best Value
Security and deployment safeguards
- Keep API keys in environment variables or a secret manager.
- Allow only HTTPS targets unless your use case explicitly requires HTTP.
- Block SSRF destinations, private IP ranges and cloud metadata endpoints.
- Sanitize or isolate user-supplied HTML and JavaScript.
- Limit output size and job duration to prevent memory and queue exhaustion.
- Use signed webhooks and verify their signatures before marking asynchronous jobs complete.
- Delete temporary screenshots containing personal or confidential data according to your retention policy.
Frequently Asked Questions
Can PHP take a screenshot without JavaScript?
PHP itself does not render modern webpages. Send the URL to a hosted browser API or run a headless Chrome package such as Browsershot; both execute the page’s JavaScript before capture.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteWhich method is easier to deploy in a serverless function?
A hosted API generally requires only an HTTPS client and credentials. Browsershot can run serverlessly, but its documented setup still requires packaging Puppeteer and Chrome; the Browsershot setup documentation points to a Lambda option.
Should I return the image or save it?
Return it directly for an immediate browser response, or save it when you need caching, later delivery, auditing or asynchronous processing. In both cases validate status and content type before treating the response as an image.
The Bottom Line
Use a hosted API when you want a small PHP integration and no Chrome operations. Use Spatie Browsershot when self-hosting and direct Puppeteer control justify the additional runtime work. For clean automated captures with usage-based billing safeguards and an MCP path for AI agents, start with ScreenshotNeo’s free 1,000-shot plan.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.

