Blog
Generate PDF from Cloudflare Worker with Headless Chrome
Intro
At the time of this post, Cloudflare Workers does not support the idea of embedding Headless Chrome or wkhtmltopdf in its environment. Workers also does not the idea of running docker containers either. This may change in the future, but for now, if you built an application on top of workers and need to generate a PDF file, you’re kind of stuck.
REST API
API2PDF will easily work with Cloudflare Workers because we provide a REST API that you can call from your workers to generate the PDF. We run Headless Chrome behind the scenes and you can convert HTML to PDF or a URL to PDF. We also offer other commands such as merging PDFs together, screenshots of URLs, HTML to Docx, Office files to PDF, and thumbnailing PDFs / Office files.
All you need to get started is an API key which you can grab for free here: https://portal.api2pdf.com/register
Sample Code
Below you will find sample code that you can modify to create a Cloudflare Worker. Replace apiKey variable with the API key you acquired from above.
//replace "YOUR-API-KEY" with your own from https://portal.api2pdf.com | |
const apiKey = "YOUR-API-KEY" | |
const baseUrl = "https://v2.api2pdf.com" | |
const urlToPdfRoute = baseUrl + "/chrome/pdf/url" | |
const htmlToPdfRoute = baseUrl + "/chrome/pdf/html" | |
const urlToImageRoute = baseUrl + "/chrome/image/url" | |
const htmlToImageRoute = baseUrl + "/chrome/image/html" | |
const mergePdfsRoute = baseUrl + "/pdfsharp/merge" | |
const libreAnyToPdfRoute = baseUrl + "/libreoffice/any-to-pdf" | |
const libreThumbnailRoute = baseUrl + "/libreoffice/thumbnail" | |
const libreHtmlToDocxRoute = baseUrl + "/libreoffice/html-to-docx" | |
async function mergePdfs(request) { | |
let result = await makeRequestToApi2Pdf(mergePdfsRoute, body) | |
return new Response(JSON.stringify(result)) | |
} | |
async function htmlToDocx(request) { | |
let result = await makeRequestToApi2Pdf(libreHtmlToDocxRoute, body) | |
return new Response(JSON.stringify(result)) | |
} | |
async function thumbnail(request) { | |
let result = await makeRequestToApi2Pdf(libreThumbnailRoute, body) | |
return new Response(JSON.stringify(result)) | |
} | |
async function anyToPdf(request) { | |
let result = await makeRequestToApi2Pdf(libreAnyToPdfRoute, body) | |
return new Response(JSON.stringify(result)) | |
} | |
async function htmlToImage(request) { | |
let result = await makeRequestToApi2Pdf(htmlToImageRoute, body) | |
return new Response(JSON.stringify(result)) | |
} | |
async function urlToImage(request) { | |
let result = await makeRequestToApi2Pdf(urlToImageRoute, body) | |
return new Response(JSON.stringify(result)) | |
} | |
async function urlToPdf(request) { | |
let result = await makeRequestToApi2Pdf(urlToPdfRoute, body) | |
return new Response(JSON.stringify(result)) | |
} | |
async function htmlToPdf(body) { | |
let result = await makeRequestToApi2Pdf(htmlToPdfRoute, body) | |
return new Response(JSON.stringify(result)) | |
} | |
async function makeRequestToApi2Pdf(endpoint, body) { | |
let pdfRequest = new Request(endpoint, | |
{ | |
method: "POST", | |
headers: { | |
Authorization: apiKey, | |
"content-type": "application/json" | |
}, | |
body: JSON.stringify(body) | |
}) | |
let response = await fetch(pdfRequest) | |
let json = await response.json() | |
return json | |
} | |
async function handleRequest(request) { | |
/* see documentation on the JSON payloads you | |
can send to each endpoint at https://www.api2pdf.com/documentation | |
*/ | |
let response = await htmlToPdf({ html: "<p>Hello World</p>" }) | |
return response | |
/* | |
other types of calls to api2pdf | |
let response = await urlToPdf({ url: "https://www.api2pdf.com" }) | |
let response = await htmlToImage({ html: "<p>Hello World</p>" }) | |
let response = await urlToImage({ url: "https://www.api2pdf.com" }) | |
let response = await htmlToDocx({ url: "http://www.api2pdf.com/wp-content/uploads/2021/01/sampleHtml.html" }) | |
let response = await thumbnail({ url: "https://www.api2pdf.com/wp-content/themes/api2pdf/assets/samples/sample-word-doc.docx" }) | |
let response = await anyToPdf({ url: "https://www.api2pdf.com/wp-content/themes/api2pdf/assets/samples/sample-word-doc.docx" }) | |
let response = await mergePdfs({ | |
urls: [ | |
"http://www.api2pdf.com/wp-content/uploads/2021/01/1a082b03-2bd6-4703-989d-0443a88e3b0f-4.pdf", | |
"http://www.api2pdf.com/wp-content/uploads/2021/01/1a082b03-2bd6-4703-989d-0443a88e3b0f-4.pdf", | |
"http://www.api2pdf.com/wp-content/uploads/2021/01/1a082b03-2bd6-4703-989d-0443a88e3b0f-4.pdf" | |
] | |
}) | |
*/ | |
} | |
addEventListener("fetch", event => { | |
event.respondWith(handleRequest(event.request)) | |
}) |
Full on documentation is available at https://www.api2pdf.com/documentation