Take a Screenshot of a Website Using PHP and Symfony Panther
Install Symfony Panther, launch Chrome or Firefox, and save a screenshot of a rendered website. Includes setup, viewport sizing, troubleshooting, and a no-driver API option.
Use Symfony Panther’s native browser client to open a URL in Chrome or Firefox, then call takeScreenshot() to save the rendered page. Install Panther with Composer, make the matching WebDriver browser driver available, and set the browser window size if you need specific screenshot dimensions. Panther is Symfony’s real-browser end-to-end testing component, and screenshot capture is supported during a test. Symfony’s end-to-end testing guide documents the setup and API.
Install Panther and a browser driver
In a Symfony project, add Panther as a development dependency:
composer require --dev symfony/panther
Panther controls Chrome or Firefox through WebDriver. Chrome needs ChromeDriver; Firefox needs geckodriver. Install a driver using the Symfony guide’s dbrekelmans/bdi workflow and run vendor/bin/bdi detect drivers, place the driver in your PATH or project drivers/ directory, or use your operating system’s package manager. The browser and driver must be compatible and available in the environment where the script runs.
If you are using Panther outside a Symfony application, install it with Composer and load Composer’s autoloader before creating a client:
require __DIR__ . '/vendor/autoload.php';
Capture a website with Chrome
This standalone example opens a website and writes a PNG screenshot to screen.png. Run it from a project where Panther and ChromeDriver are installed:
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Panther\Client;
$client = Client::createChromeClient();
try {
$client->request('GET', 'https://example.com');
$client->takeScreenshot(__DIR__ . '/screen.png');
} finally {
$client->quit();
}
request() navigates the real browser to the URL; takeScreenshot() captures the current rendered page. The screenshot path may be relative or absolute. Use a directory the PHP process can write to. For a Symfony functional end-to-end test, use PantherTestCase and static::createPantherClient(); PantherTestCase starts the application using Symfony’s built-in PHP web server.
Use Firefox or choose the browser for your test
To use Firefox, make sure geckodriver is installed and use Panther’s Firefox client:
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Panther\Client;
$client = Client::createFirefoxClient();
try {
$client->request('GET', 'https://example.com');
$client->takeScreenshot(__DIR__ . '/screen.png');
} finally {
$client->quit();
}
Choose the browser your application needs to support, and check that its driver is available locally and in CI. The Symfony documentation covers both browser choices; it does not establish a universal performance or screenshot-fidelity winner between Chrome and Firefox.
Set the screenshot viewport
The browser window size affects the screenshot’s dimensions and the page’s responsive layout. For Chrome, Panther accepts browser arguments such as --window-size=1500,4000:
$client = Client::createChromeClient(null, ['--window-size=1500,4000']);
$client->request('GET', 'https://example.com');
$client->takeScreenshot(__DIR__ . '/screen.png');
That size is an example from Symfony’s documentation, not a universal setting. Choose a width that matches the desktop or mobile layout you want to inspect. A tall window can capture more vertical content in the browser viewport; confirm the output dimensions and page behavior for your particular browser and page.
For Firefox, use a WebDriver dimension when configuring the browser window, as shown in Symfony’s guide:
use Facebook\WebDriver\Firefox\FirefoxDriver;
use Facebook\WebDriver\WebDriverDimension;
$client = Client::createFirefoxClient();
$client->manage()->window()->setSize(new WebDriverDimension(1500, 1200));
$client->request('GET', 'https://example.com');
$client->takeScreenshot(__DIR__ . '/screen.png');
Set the size before navigation when you want the page to lay out at that viewport from the start. If a responsive page changes after resizing, navigate again before capturing.
Use Panther in a Symfony test
When the screenshot is part of an application test, create the client through PantherTestCase. The client can visit your application and capture a state at the point in the test where it matters:
<?php
namespace App\Tests;
use Symfony\Component\Panther\PantherTestCase;
final class PageScreenshotTest extends PantherTestCase
{
public function testPageCanBeCaptured(): void
{
$client = static::createPantherClient();
$client->request('GET', '/');
$client->takeScreenshot(__DIR__ . '/homepage.png');
}
}
This pattern is useful for investigating an end-to-end test failure or recording a particular application state. Ensure the output directory exists and is writable. Avoid relying on a screenshot file as the only assertion: test the behavior you care about separately.
Browser client limitations and headless operation
Use Panther’s native Chrome or Firefox browser client for screenshots. The alternative BrowserKit clients do not support JavaScript, CSS, or screenshot capture, according to Symfony’s end-to-end testing guide. BrowserKit can suit faster tests that do not need a rendered browser, but it is not a substitute for this screenshot workflow.
Panther runs headless for CI use. To see the browser while debugging, the guide documents the PANTHER_NO_HEADLESS environment variable. Browser visibility and driver setup should be configured for the environment running the test; a local graphical session may not exist in CI.
Common errors and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Panther cannot start Chrome or Firefox | The browser is missing, the WebDriver executable is not discoverable, or the driver and browser are incompatible. | Install the browser and matching driver. Check the Symfony guide’s driver detection instructions, then verify the executable is on PATH or in the project’s drivers/ directory. |
| “Class not found” for Panther classes | The package is not installed in this project or Composer’s autoloader was not loaded. | Run composer require --dev symfony/panther in the project and include vendor/autoload.php in standalone scripts. |
| No screenshot file appears | The destination directory does not exist or PHP cannot write there; the browser may also have failed before the capture call. | Use an absolute path in a known writable directory, create that directory first, and inspect any browser startup or navigation error before takeScreenshot(). |
| Screenshot shows the wrong responsive layout or size | The browser viewport does not match the intended dimensions. | Configure Chrome’s window-size argument or set Firefox’s WebDriverDimension before loading the page; capture after navigation at the intended size. |
| Page content is unstyled or JavaScript-dependent content is missing | A BrowserKit client was used, or the page’s resources/scripts did not load in the real browser. | Use a native Chrome or Firefox Panther client. Check the target page and browser environment if its CSS or scripts still fail to load. |
| Browser opens visibly in a headless CI job | Headless configuration was changed or the environment variable for debugging is set. | Use the default headless behavior for CI. Set PANTHER_NO_HEADLESS only when you intend to display the browser for local debugging. |
Performance, reliability, and cost
A Panther screenshot starts and drives a real browser, so it depends on the browser binary, WebDriver, and target page loading successfully. For repeatable captures, pin the browser and driver versions in your environment, set the viewport deliberately, and use the same environment in local runs and CI. The reviewed Symfony sources do not publish a universal Chrome-versus-Firefox speed ranking or a benchmark for capture time.
Expect browser installation and maintenance as part of the workflow, especially across CI images. Screenshot files also consume storage, so keep only the artifacts needed for debugging or comparison. Panther itself is installed as a Composer package; browser and CI infrastructure costs depend on your environment. The Symfony sources provide no numeric cost or performance estimate for a typical capture.
Or skip the browser setup
If you want a screenshot without installing and maintaining ChromeDriver or geckodriver, ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request returns an image or PDF. It removes cookie banners, newsletter popups, and chat widgets before the capture; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots, and 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000.
Here is the cURL request; see the ScreenshotNeo API documentation for the API options:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
Equivalent Python and Node.js calls:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);
Replace YOUR_API_KEY with your key. The API also supports PNG, JPEG, and PDF output, full-page capture, selectors, device presets, custom CSS and JavaScript, wait conditions, request blocking, caching, and bulk capture. Sign up for 1,000 free screenshots a month with no card.
FAQ
Does Panther capture a real rendered page?
Yes. Use its native Chrome or Firefox client, which drives a real browser through WebDriver.
Can I use Panther without Symfony?
Yes. Install the Composer package and include vendor/autoload.php in your standalone script.
Can BrowserKit take the screenshot instead?
No. Symfony documents that Panther’s BrowserKit alternatives do not support screenshot capture, CSS, or JavaScript.
Does the screenshot always cover the full page?
The cited Panther guidance describes browser screenshots and viewport sizing. Set the browser dimensions for the region you need and check the resulting capture for your page and browser.


