Generate PDFs Using HTML and CSS
As seen in the Deploy a Browser Run Worker guide, Browser Run can be used to generate screenshots for any given URL. Alongside screenshots, you can also generate full PDF documents for a given webpage, and can also provide the webpage markup and style ourselves.
You can generate PDFs with Browser Run in two ways:
- Quick Actions: Use the /pdf endpoint. This is ideal if you do not need to customize rendering behavior.
- Puppeteer or Playwright: Use browser automation within Workers for additional control and customization.
Choose the method that best fits your use case.
The following example shows you how to generate a PDF using Puppeteer.
- Use the
create-cloudflareCLI to generate a new Hello World Cloudflare Worker script:
npm create cloudflare@latest -- browser-worker yarn create cloudflare browser-worker pnpm create cloudflare@latest browser-worker - Install
@cloudflare/puppeteer, which allows you to control the Browser Run instance:
npm i -D @cloudflare/puppeteer yarn add -D @cloudflare/puppeteer pnpm add -D @cloudflare/puppeteer bun add -d @cloudflare/puppeteer - Add your Browser Run binding to your new Wrangler configuration:
{ "browser": { "binding": "BROWSER", },}[browser]binding = "BROWSER"- Replace the contents of
src/index.ts(orsrc/index.jsfor JavaScript projects) with the following skeleton script:
import puppeteer from "@cloudflare/puppeteer";
const generateDocument = (name: string) => {};
export default { async fetch(request, env) { const { searchParams } = new URL(request.url); let name = searchParams.get("name");
if (!name) { return new Response("Please provide a name using the ?name= parameter"); }
const browser = await puppeteer.launch(env.BROWSER); const page = await browser.newPage();
// Step 1: Define HTML and CSS const document = generateDocument(name);
// Step 2: Send HTML and CSS to our browser await page.setContent(document);
// Step 3: Generate and return PDF
return new Response(); },};Rather than using Browser Run to navigate to a user-provided URL, manually generate a webpage, then provide that webpage to the Browser Run instance. This allows you to render any design you want.
For this example, we are going to take in user-provided content (via a '?name=' parameter), and have that name output in the final PDF document.
To start, fill out your generateDocument function with the following:
const generateDocument = (name: string) => { return `<!DOCTYPE html><html lang="en"> <head> <meta charset="utf-8" /> <style> html, body, #container { width: 100%; height: 100%; margin: 0; } body { font-family: Baskerville, Georgia, Times, serif; background-color: #f7f1dc; } strong { color: #5c594f; font-size: 128px; margin: 32px 0 48px 0; } em { font-size: 24px; } #container { flex-direction: column; display: flex; align-items: center; justify-content: center; text-align: center; } </style> </head>
<body> <div id="container"> <em>This is to certify that</em> <strong>${name}</strong> <em>has rendered a PDF using Cloudflare Workers</em> </div> </body></html>`;};