How to generate a PDF from a URL in Node.js
Generate a PDF from any URL in Node.js with one fetch call. No Puppeteer, no Chromium binary, no headless browser process to manage.
How to Generate a PDF from a URL in Node.js
The standard approach to PDF generation in Node.js: spin up Puppeteer, launch a Chromium process, navigate to the URL, call page.pdf(), handle memory leaks, then clean up the browser. That's 50+ lines of lifecycle management for a file conversion.
An API call does the same thing in 10:
import fs from 'fs';
const res = await fetch('https://api.pagebolt.dev/v1/pdf', {
method: 'POST',
headers: {
'x-api-key': process.env.PAGEBOLT_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://example.com/report',
format: 'A4',
printBackground: true,
blockBanners: true
})
});
const buffer = Buffer.from(await res.arrayBuffer());
fs.writeFileSync('output.pdf', buffer);
No dependencies beyond Node's built-in fetch (Node 18+). No browser process, no memory management.
Common options
{
url: 'https://example.com',
format: 'A4', // A4, Letter, Legal, A3
printBackground: true, // include CSS backgrounds
margin: {
top: '20mm',
bottom: '20mm',
left: '15mm',
right: '15mm'
},
landscape: false,
blockBanners: true, // strip cookie consent popups
blockAds: true
}
Generate from raw HTML
If you're building invoices, reports, or receipts from templates, pass HTML directly instead of a URL:
const html = `
<html>
<body style="font-family: sans-serif; padding: 40px">
<h1>Invoice #1042</h1>
<p>Amount due: $299.00</p>
</body>
</html>
`;
const res = await fetch('https://api.pagebolt.dev/v1/pdf', {
method: 'POST',
headers: {
'x-api-key': process.env.PAGEBOLT_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ html, format: 'A4', printBackground: true })
});
In an Express route
app.get('/invoice/:id', async (req, res) => {
const invoiceHtml = await buildInvoiceHtml(req.params.id);
const pdfRes = await fetch('https://api.pagebolt.dev/v1/pdf', {
method: 'POST',
headers: {
'x-api-key': process.env.PAGEBOLT_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ html: invoiceHtml, format: 'A4', printBackground: true })
});
const buffer = Buffer.from(await pdfRes.arrayBuffer());
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename="invoice-${req.params.id}.pdf"`);
res.send(buffer);
});
In AWS Lambda
The same code runs without modification in Lambda — no Chromium layer, no @sparticuz/chromium, no binary compatibility issues. The browser runs on PageBolt's infrastructure.
What you skip vs Puppeteer
| Puppeteer | PageBolt API | |
|---|---|---|
| Browser binary | Required (~300MB) | None |
| Memory per request | 200-500MB | Negligible |
| Cold start | 5-10s | Milliseconds |
| Concurrent PDFs | Complex pool mgmt | Fire-and-forget |
| Deployment size | Large | Kilobytes |
Try it free — 100 requests/month, no credit card. → pagebolt.dev
Get Started Free
100 requests/month, no credit card
Screenshots, PDFs, video recording, and browser automation — no headless browser to manage.
Get Your Free API Key →