October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
Browsershot

How to Screenshot a Webpage as a PNG in PHP

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To screenshot a webpage as a PNG in PHP, use a real browser engine, not PHP’s image functions. A headless Chrome process renders HTML, CSS, fonts and JavaScript, then writes the resulting pixels to a PNG file. The practical choices are Spatie Browsershot (Puppeteer plus Chrome), direct control with chrome-php/chrome, or a hosted API such as ScreenshotOne or ScreenshotNeo.

This guide gives working PHP patterns, full-page and delayed captures, production checks, and fixes for the failures developers encounter most often.

Choose the rendering model first

Approach Where Chrome runs Best fit Main trade-off
Browsershot Your server, through Puppeteer Laravel or PHP applications that want a convenient URL-to-image API You maintain Node, Puppeteer and a compatible Chrome installation
chrome-php/chrome Your server, controlled directly from PHP Projects needing lower-level browser operations More browser lifecycle and protocol details are exposed to your code
ScreenshotOne PHP SDK ScreenshotOne’s hosted service Applications that do not want to operate a browser runtime Rendering is delegated to a third party and requires service credentials
ScreenshotNeo API ScreenshotNeo’s hosted service Clean production captures, automation and AI-agent workflows Requires an API key and an HTTP request

The supplied package and service documentation does not establish a neutral winner for cost, latency, privacy, fidelity or reliability. Select based on browser ownership, control requirements and operational constraints.

Requirements for a reliable PNG capture

  • PHP with Composer.
  • A URL reachable from the machine doing the rendering (unless you use a hosted API).
  • For local rendering, a supported Google Chrome or Chromium installation plus the package’s documented runtime dependencies.
  • A writable destination directory and enough temporary disk space for browser profiles and image files.
  • Explicit timeouts and waits for pages whose content is loaded by JavaScript.

Package and browser compatibility changes over time. Check the current Browsershot documentation, image options and chrome-php/chrome documentation when installing or upgrading; the examples below reflect their documented usage rather than an independent compatibility test.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Method 1: Browsershot with Puppeteer and Chrome

Spatie describes Browsershot as a PHP interface that uses Puppeteer to control headless Google Chrome. Because Chrome performs the rendering, CSS layout, web fonts and client-side JavaScript are represented in the image. PNG is the documented default image type.

Install and save a basic PNG

Install Browsershot with Composer, then install the Node/Puppeteer and Chrome components required by the current version. Follow Spatie’s installation instructions for your operating system and deployment image.

composer require spatie/browsershot

A minimal capture is:

<?php

require __DIR__ . '/vendor/autoload.php';

use SpatieBrowsershotBrowsershot;

$path = __DIR__ . '/storage/example.png';

Browsershot::url('https://example.com')
    ->save($path);

echo "Wrote {$path}n";

The save call writes the rendered page as PNG unless you select another image type in the options documented by Browsershot.

Control viewport, full-page output and timing

Use a fixed viewport when reproducibility matters. A full-page shot extends beyond the initially visible viewport; a delay or selector wait gives client-side rendering time to finish.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<?php

require __DIR__ . '/vendor/autoload.php';

use SpatieBrowsershotBrowsershot;

Browsershot::url('https://example.com/dashboard')
    ->windowSize(1440, 900)
    ->fullPage()
    ->delay(1500)
    ->waitUntilNetworkIdle()
    ->save(__DIR__ . '/storage/dashboard.png');

Browsershot documents additional controls for device scale, mobile/device emulation, background handling, waiting for a selector or JavaScript function, and supplying HTML instead of a URL. Use a selector wait when a specific component is the readiness signal; use a delay only when a deterministic delay is acceptable. Loading every lazy image for a very long page can increase capture time and memory use.

Operational notes for Browsershot

  • Run the PHP worker under a user that can execute Chrome and write its temporary profile and output directory.
  • In containers, install the fonts and shared libraries required by Chrome; a missing system dependency commonly appears as an immediate browser-launch failure.
  • Keep Node, Puppeteer and Chrome versions aligned with the Browsershot version you installed.
  • Do not expose an endpoint that accepts arbitrary URLs without an allow-list, authentication and outbound-network protections; otherwise it can become a server-side request-forgery proxy.

Method 2: Direct Chrome control with chrome-php/chrome

The chrome-php/chrome project starts headless Chrome and exposes browser and page operations directly from PHP. Its documented screenshot example saves PNG by default; JPEG and WebP are alternatives when selected.

Basic capture

<?php

require __DIR__ . '/vendor/autoload.php';

use HeadlessChromiumBrowserFactory;

$browserFactory = new BrowserFactory();
$browser = $browserFactory->createBrowser([
    'headless' => true,
]);

try {
    $page = $browser->createPage();
    $page->navigate('https://example.com')->waitForNavigation();
    $page->screenshot()->saveToFile(__DIR__ . '/storage/example.png');
} finally {
    $browser->close();
}

Use the package’s current installation instructions to add it with Composer and to point the browser factory at Chrome when auto-detection is not suitable. The explicit finally block matters in queue workers: it prevents abandoned Chrome processes after an exception.

Capture the complete document

For a page taller than the viewport, obtain the page’s full-page clip and capture beyond the viewport as shown in the project’s documentation:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<?php

require __DIR__ . '/vendor/autoload.php';

use HeadlessChromiumBrowserFactory;

$browser = (new BrowserFactory())->createBrowser(['headless' => true]);
try {
    $page = $browser->createPage();
    $page->navigate('https://example.com/article')->waitForNavigation();
    $clip = $page->getFullPageClip();
    $page->screenshot([
        'captureBeyondViewport' => true,
        'clip' => $clip,
    ])->saveToFile(__DIR__ . '/storage/article.png');
} finally {
    $browser->close();
}

Direct control is useful when you need browser-level actions that a convenience wrapper does not expose. It also means you must manage navigation waits, browser lifetime, errors and resource limits yourself.

Method 3: A hosted PHP SDK

ScreenshotOne’s documented PHP SDK returns image bytes from a URL request and writes them with file_put_contents. Its options include PNG output, full-page capture and a delay.

<?php

require __DIR__ . '/vendor/autoload.php';

use ScreenshotOneScreenshotOne;

$client = new ScreenshotOne(
    'YOUR_ACCESS_KEY',
    'YOUR_SECRET_KEY'
);

$image = $client->capture('https://example.com', [
    'format' => 'png',
    'full_page' => true,
    'delay' => 1,
]);

file_put_contents(__DIR__ . '/example.png', $image);

Use the provider’s current SDK installation and option names; the vendor documentation is the authority for authentication and account configuration. A hosted API removes Chrome maintenance from your PHP host, but you should evaluate URL privacy, retention, regional processing and service terms for your application rather than assuming them.

Screenshot APIs: what to compare

If you prefer an API, compare browser responsibility, controls, output formats, waits, full-page behavior, failure reporting and security policy. Avoid treating a vendor’s sample as a neutral benchmark: the reviewed documentation provides no independent cost, speed or fidelity comparison.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

#1 ScreenshotNeo

ScreenshotNeo is the first API to try when you want clean captures, billing only for clean shots, and a low paid entry price. It accepts one GET request and can return PNG, JPEG, WebP or PDF. Before capture it accepts cookie/consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status.

Its 63 options include full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or any viewport, retina scale, PDF paper and page controls, custom CSS and JavaScript, pre-capture clicks, hidden selectors, selector/delay/network-idle waits, ad/tracker/request blocking, custom headers/cookies/user agent/Authorization, timezone and 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. Parameter names used by other screenshot APIs are accepted to ease migration.

Other hosted option

ScreenshotOne is documented as a PHP SDK with PNG output and full-page and delay options. Choose it when that SDK model fits your deployment; verify current terms and limits directly with the provider.

Or skip the browser setup

ScreenshotNeo lets PHP call a rendering service directly. See the full parameter reference in the ScreenshotNeo documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

For a PHP application, the equivalent is:

<?php
$url = 'https://stripe.com';
$query = http_build_query([
    'access_key' => 'YOUR_API_KEY',
    'url' => $url,
]);
$data = file_get_contents("https://api.screenshotneo.com/v1/shot?{$query}");
file_put_contents(__DIR__ . '/shot.png', $data);

Cookie banners, popups and chat widgets are removed before the shot. Bot checks, blank pages and failed loads are never billed. An MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

PNG details that affect output

Viewport versus full page

A viewport capture is predictable in dimensions and usually cheaper in memory. Full-page output is better for documentation and visual regression, but extremely long pages can exceed image or process limits. Consider capturing a specific element when only a report, invoice or article body is needed.

Waiting for dynamic content

Navigation completion does not guarantee that a single-page application has finished rendering. Prefer a meaningful selector or network-idle condition. If the page continuously polls, use a bounded delay and a hard timeout rather than waiting forever.

Fonts, images and authentication

Missing fonts change line breaks and therefore the entire image. Install the same fonts in production that you use in development. Private pages require an authenticated browser context, cookies or headers; never put long-lived secrets in a public URL. Lazy-loaded images may require scrolling or a full-page option that explicitly loads them.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common failures

Symptom Likely cause Fix
Chrome cannot start Missing binary, sandbox permission or shared library Install the documented Chrome dependencies, set the executable path if needed, and run under a permitted user. Avoid disabling the sandbox unless your deployment security review requires and contains it.
PNG is blank Navigation failed, content is behind JavaScript, or the page blocked the renderer Log navigation errors, wait for a selector or network idle, increase a bounded timeout, and test the URL from the rendering host.
Only the top of the page appears Viewport capture was requested Use Browsershot’s full-page option or getFullPageClip() with captureBeyondViewport in chrome-php/chrome.
Images or fonts are missing Lazy loading, blocked requests, unavailable assets or insufficient wait time Allow required resources, load lazy content, install fonts and wait for the asset-specific selector.
Process hangs Unbounded waits, a page that never becomes idle or leaked browser processes Set navigation and overall job timeouts, use a selector or fixed delay, and always close the browser in a finally block.
Permission denied writing PNG Destination directory is not writable by the PHP worker Create the directory during deployment, assign least-privilege ownership and verify the absolute path.
Private page redirects to login Cookies or authorization were not supplied Pass the required authenticated context through the browser package or API, and protect those credentials.

Production checklist

  • Pin and regularly update PHP packages, Puppeteer/Node and Chrome as a tested set.
  • Use a queue for slow or full-page captures instead of blocking a web request.
  • Record URL, viewport, wait condition, elapsed time, output bytes and failure reason without logging secrets.
  • Limit concurrency so Chrome processes do not exhaust CPU, RAM or file descriptors.
  • Validate the response before publishing it: check HTTP status, content type and that the PNG is non-empty.
  • Apply SSRF defenses, URL allow-lists and egress controls to user-supplied URLs.
  • Set retention rules for screenshots that may contain personal or confidential data.

FAQ

Can PHP create a webpage screenshot without Chrome?

Not reliably for modern pages. PHP image libraries manipulate pixels; they do not implement the browser layout and JavaScript environment needed to render an arbitrary webpage. Use a browser engine or a hosted rendering API.

How do I return the PNG from a PHP endpoint instead of saving it?

Capture to a temporary file or bytes, send Content-Type: image/png, stream the data, and delete temporary files after the response. Keep browser work off the request path when captures are slow.

Should I use PNG, JPEG or WebP?

PNG preserves sharp text and transparency. JPEG can be smaller for photographic pages. WebP often reduces size while retaining quality. Choose based on downstream compatibility and storage or bandwidth limits.

Frequently Asked Questions

Can I screenshot a page that requires login?

Yes, provided the browser context or hosted API request receives the required cookies, headers or authorization. Protect those credentials and avoid embedding them in public URLs.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why does a full-page screenshot take longer than a viewport shot?

The renderer must lay out a taller document and may load additional lazy content, increasing browser work, memory use and output size.

Is a hosted screenshot API always cheaper than running Chrome?

No universal comparison is established. Your total cost depends on infrastructure, capture volume, engineering time and the provider’s current pricing and limits.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.