Rendral

Stack · Cloudflare Workers

Generate PDFs in Cloudflare Workers

Workers don't run Node and have no filesystem or process model, so spawning a browser is not merely awkward — it is impossible. Puppeteer, Playwright and every wkhtmltopdf wrapper are off the table by design.

A fetch call, however, is exactly what the runtime is built for. Render your HTML at the edge, POST it, and stream the PDF straight back to the client without ever buffering it in the isolate.

01Call it from Cloudflare Workers

render.ts
// src/index.js — deploy with wrangler
export default {
  async fetch(request, env) {
    const html = await buildInvoiceHtml(request);

    const upstream = await fetch("https://rendral.com/api/v1/pdf", {
      method: "POST",
      headers: {
        Authorization: "Bearer " + env.RENDRAL_API_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        html,
        options: { format: "A4", pageNumbers: true },
      }),
    });

    if (!upstream.ok) {
      return new Response("Render failed", { status: 502 });
    }

    // Stream it through — never buffered in the isolate.
    return new Response(upstream.body, {
      headers: {
        "Content-Type": "application/pdf",
        "Content-Disposition": 'inline; filename="invoice.pdf"',
      },
    });
  },
};

Frequently asked

Why can't Workers run Puppeteer directly?

The runtime is V8 isolates, not Node: no child processes, no filesystem, no binaries. Chrome needs all three, so browser automation can't run inside a Worker.

Does streaming count against Worker CPU time?

Barely. Passing upstream.body through is I/O, not CPU, so the isolate stays well inside its limit even for large documents.

Where do I store the API key?

As a Worker secret: wrangler secret put RENDRAL_API_KEY. It arrives on the env argument and is never exposed to the client.

Can I cache generated PDFs?

Yes — put the response in the Cache API or R2 keyed by document id. Identical HTML is also served from the render cache, so repeats are fast anyway.

Related

Start rendering in minutes.

A free tier, five endpoints, and SDKs for Node and Python.