Recommended Free Tools
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Guzzle retrieves the HTML; it does not turn HTML into a PDF. To convert a page you fetch with Guzzle, pass the response body to a PDF renderer such as Dompdf, then render and save or stream the result. The basic flow is get() → read the body → loadHtml() → render() → output the PDF.
Install Guzzle and a PDF renderer
Use Composer to install both libraries:
composer require guzzlehttp/guzzle dompdf/dompdf
Guzzle can use cURL or PHP’s stream wrapper for HTTP requests; its documentation recommends Composer for installation. Check the current package requirements when choosing versions, because the Guzzle documentation’s PHP requirement can change. Guzzle documentation
Dompdf is a practical fit for a Composer-based workflow. It is a PHP HTML layout and rendering engine whose core layout support is primarily CSS 2.1, with selected CSS3 features. It is not a full browser, so modern CSS or JavaScript-heavy pages may not render as they do in Chrome. Dompdf project
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteFetch HTML with Guzzle and save a PDF
This complete example requests a public page, checks the response content type, loads the response body into Dompdf, and writes the rendered PDF to disk. Replace the example URL with a page you are permitted to access.
#1 Best Overall
<?php
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttpClient;
use DompdfDompdf;
$url = 'https://example.com/page';
$outputPath = __DIR__ . '/page.pdf';
$client = new Client([
'timeout' => 20,
'connect_timeout' => 10,
'allow_redirects' => true,
'http_errors' => false,
]);
try {
$response = $client->get($url, [
'headers' => [
'Accept' => 'text/html,application/xhtml+xml',
],
]);
$status = $response->getStatusCode();
$contentType = strtolower($response->getHeaderLine('Content-Type'));
if ($status < 200 || $status >= 300) {
throw new RuntimeException("Unexpected HTTP status: {$status}");
}
if (strpos($contentType, 'text/html') === false &&
strpos($contentType, 'application/xhtml+xml') === false) {
throw new RuntimeException("Expected HTML; received: {$contentType}");
}
$html = (string) $response->getBody();
if ($html === '') {
throw new RuntimeException('The response body is empty.');
}
$dompdf = new Dompdf();
$dompdf->loadHtml($html, 'UTF-8');
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
$pdf = $dompdf->output();
if (file_put_contents($outputPath, $pdf) === false) {
throw new RuntimeException("Could not write PDF to {$outputPath}");
}
echo "Saved PDF to {$outputPath}" . PHP_EOL;
} catch (Throwable $e) {
fwrite(STDERR, 'PDF conversion failed: ' . $e->getMessage() . PHP_EOL);
exit(1);
}
The cast (string) $response->getBody() reads the response stream into a string. You can instead call $response->getBody()->getContents() when you want to consume the stream explicitly; do not expect a second read to return the same content after a stream has already been consumed.
Dompdf’s documented sequence is to load HTML, set paper size and orientation, render, and then stream or retrieve the output. Dompdf usage documentation
Return the PDF as a browser download
If this script is itself serving the response, send the PDF bytes with appropriate headers instead of writing a file. Do not print debug messages or whitespace before the headers.
$pdf = $dompdf->output();
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="page.pdf"');
header('Content-Length: ' . strlen($pdf));
echo $pdf;
Use Dompdf’s built-in stream method
For a direct download, Dompdf can also stream the rendered document:
Rank #2
$dompdf->stream('page.pdf', ['Attachment' => true]);
Set Attachment to false if the browser should try to display the PDF inline. The actual behavior still depends on the browser and response handling.
Understand what will and will not render
HTML and CSS support
Dompdf is suited to many document-style pages with ordinary text, tables, images, stylesheets, and print rules. Its layout engine is mainly CSS 2.1 with selected CSS3 support, not a modern browser’s complete rendering stack. Test the exact templates you need, especially when they rely on grid, flexbox, advanced selectors, or other newer layout behavior. Dompdf project
JavaScript-dependent pages
The Guzzle request downloads the server’s HTTP response; it does not execute the page’s JavaScript. If the page fills in its content client-side, the response HTML may not contain the content you see in a browser. Dompdf is not a JavaScript browser engine. For a page that must run scripts or closely mirror a modern browser, consider a headless Chrome workflow rather than expecting Guzzle plus Dompdf to reproduce it. The mPDF manual likewise points to headless Chrome when modern CSS fidelity or faithful mirroring of an existing page is the priority. mPDF manual
Remote images and stylesheets
A page may refer to assets by relative URLs, or load images and stylesheets from another host. Those references are not automatically equivalent to a self-contained HTML document. Dompdf disables remote access by default; enable it only when required, and restrict the permitted sources rather than letting untrusted input make arbitrary network requests. Dompdf project
For predictable output, prefer controlled HTML with absolute asset URLs or inline the assets your template needs. Verify that fonts and image formats are supported by the renderer and available to the PHP process. A successful HTTP fetch of the HTML does not prove the renderer can retrieve every referenced asset.
Choose the rendering engine for the page
| Engine | Good fit | Trade-off to check |
|---|---|---|
| Dompdf | PHP application using Composer and common document-oriented HTML/CSS. | Mostly CSS 2.1; not a JavaScript-capable browser. Remote access is disabled by default. |
| mPDF | Generating PDF from UTF-8 HTML in PHP, including workflows that use its custom HTML tags. | Its own manual describes the project as dated and warns that outside HTML/CSS must be vetted and sanitized. mPDF manual |
| wkhtmltox | A separate conversion engine using QtWebKit to render HTML into PDF and image formats. | It brings native/runtime deployment considerations beyond adding a PHP package. PHP wkhtmltox manual |
| Headless Chrome | Pages that require modern browser CSS or JavaScript execution, or close browser-like page rendering. | Requires running and maintaining a browser-based rendering environment; the cited sources do not establish a universal best engine. |
Choose by testing representative pages: CSS fidelity, whether scripts must execute, deployment dependencies, fonts and images, page-break behavior, and whether the HTML or its resource URLs are trusted. No one renderer is best for every PHP project.
Control security and resource use
Restrict the URL being fetched
If a user can supply the URL, do not pass it directly to Guzzle without policy checks. A server-side fetch endpoint can otherwise be abused to request internal services or other destinations your application should not reach. Allow only expected schemes and hosts, and account for redirects when applying those restrictions. Keep connect and total request timeouts bounded.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Treat HTML as untrusted input
Do not assume that browser-level escaping makes arbitrary HTML/CSS safe to render on the server. mPDF explicitly warns that outside HTML/CSS must be vetted and sanitized. Apply a suitable allowlist or use trusted templates and data rather than accepting raw markup from arbitrary users. mPDF manual
Rank #4
Limit the work per request
Set limits appropriate to your application for response bytes, conversion time, and output size. Large documents, many high-resolution images, or slow remote assets can consume significant memory and time. For an application that accepts user jobs, enforce quotas and consider moving rendering out of the web request into a worker with a bounded queue.
Validate the HTTP status and content type before rendering. This prevents an error page, login screen, JSON response, or unrelated download from being mistaken for the intended HTML. The sample uses http_errors => false so it can report the status itself; without that setting, Guzzle may throw for unsuccessful HTTP responses.
Troubleshoot common failures
- The PDF contains an error page or is empty: Inspect the HTTP status, final URL after redirects, content type, and body length. The requested URL may return an access-denied page, authentication screen, or no content.
- Images or CSS are missing: Check whether resource URLs are absolute, whether the renderer is allowed to access remote resources, and whether those hosts are reachable from the PHP environment. Keep any remote-access permission limited to approved origins.
- The result looks different from the website: Check for JavaScript-generated content and CSS features beyond Dompdf’s support. Use a browser engine for pages that depend on modern layout or client-side rendering.
- The PDF is truncated or the process runs out of memory: Reduce the HTML and image size, limit the number of pages or assets, and give the worker appropriate resource limits. Avoid converting unbounded user documents in a synchronous request.
- Download headers fail or the PDF is corrupted: Ensure no warnings, notices, debug output, or whitespace precedes the PDF response. Use either Dompdf’s stream method or a single explicit header-and-output path, not both.
- Composer reports a PHP version conflict: Check the PHP requirement of the exact package versions selected in
composer.lockand the PHP runtime that executes the job. Guzzle’s stable documentation has stated PHP 7.2.5 as a requirement, but package requirements are version-dependent; verify before pinning. Guzzle documentation
Or skip the browser setup
If your goal is a screenshot or PDF capture of a live URL rather than a PHP-rendered document, ScreenshotNeo is a website screenshot API and MCP server. One GET request can return a PNG, JPEG, WebP, or PDF; its clean-shot options can accept consent banners and remove known consent platforms, newsletter popups, and chat widgets before capture.
Windows 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 reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteFor a PDF capture, use its API endpoint with the PDF output option as documented. A basic image capture call looks like this:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for PDF parameters and other options. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, with verdict and billing information in response headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Sign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month with no card.
FAQ
Can I convert a local HTML string without making a Guzzle request?
Yes. Guzzle is only needed to retrieve remote HTML; pass your existing HTML string directly to Dompdf’s loadHtml(), then render and output it.
Does Guzzle produce the PDF bytes?
No. Guzzle performs the HTTP request and supplies the response body. A renderer such as Dompdf creates the PDF.
Which Dompdf version should I use?
Use a version compatible with your PHP runtime and verify the installed version in your dependency lockfile. The project’s version information is time-sensitive; the project snapshot identifies 3.1.5 in 2026, which should not be treated as a recommendation to install that version without checking compatibility. Dompdf project
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.

