How to Take Screenshots and Generate PDFs in PHP (Without wkhtmltopdf)
PHP PDF generation has always been painful — wkhtmltopdf needs a binary, Dompdf can't render JavaScript, and Browsershot requires Node.js. Here's the clean path: one HTTP request, binary response, no system dependencies.
PHP PDF generation has always been painful. wkhtmltopdf requires a binary installation and struggles with modern CSS and JavaScript. Dompdf is pure PHP but can't render JavaScript-heavy pages. mPDF is similar. Browsershot (Spatie) wraps Puppeteer, which means Node.js on your server.
Here's the clean path: one HTTP request, binary response, no system dependencies.
Screenshot from a URL
<?php
function screenshot(string $url): string
{
$ch = curl_init('https://pagebolt.dev/api/v1/screenshot');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'x-api-key: ' . $_ENV['PAGEBOLT_API_KEY'],
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'url' => $url,
'fullPage' => true,
'blockBanners' => true,
]),
]);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
// Save to disk
file_put_contents('screenshot.png', screenshot('https://example.com'));
PDF from a URL
function pdfFromUrl(string $url): string
{
$ch = curl_init('https://pagebolt.dev/api/v1/pdf');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'x-api-key: ' . $_ENV['PAGEBOLT_API_KEY'],
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'url' => $url,
'blockBanners' => true,
]),
]);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
file_put_contents('page.pdf', pdfFromUrl('https://yourapp.com/invoice/1042'));
PDF from HTML (replacing wkhtmltopdf / Dompdf)
Render your PHP template to an HTML string first, then send it:
function pdfFromHtml(string $html): string
{
$ch = curl_init('https://pagebolt.dev/api/v1/pdf');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'x-api-key: ' . $_ENV['PAGEBOLT_API_KEY'],
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['html' => $html]),
]);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
// Build your HTML however you like
ob_start();
include 'templates/invoice.php';
$html = ob_get_clean();
$pdf = pdfFromHtml($html);
file_put_contents("invoice-{$invoiceId}.pdf", $pdf);
Laravel controller example
use Illuminate\Http\Response;
class InvoiceController extends Controller
{
public function download(Invoice $invoice): Response
{
$html = view('invoices.pdf', compact('invoice'))->render();
$ch = curl_init('https://pagebolt.dev/api/v1/pdf');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'x-api-key: ' . env('PAGEBOLT_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['html' => $html]),
]);
$pdf = curl_exec($ch);
curl_close($ch);
return response($pdf, 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => "attachment; filename=\"invoice-{$invoice->id}.pdf\"",
]);
}
}
No Composer package, no binary, no Node.js. The Blade template renders as normal — just swap the PDF generation step.
Deployment
No buildpacks, no apt-get, no binary layer. Works on shared hosting, Heroku, Laravel Forge, or any PHP environment with outbound HTTPS. Add PAGEBOLT_API_KEY to your .env and deploy as normal.
Get Started Free
100 requests/month, no credit card
Screenshots, PDFs, and video recordings from your PHP app — no wkhtmltopdf, no Dompdf, no binary dependencies.
Get Your Free API Key →