RenderPDFs/Tutorials/Next.js
📘 Quickstart · 5 minutes

Generate PDFs in Next.js

Generate PDFs from HTML, Markdown, URLs or templates in a Next.js App Router project — using the renderpdfs npm package server-side.

1. Install

RenderPDFs uses a plain REST API — no SDK required. For Next.js, install the dependency below and grab your API key from renderpdfs.com/signup (free, 100 PDFs/month, no credit card).

Installbash
npm install renderpdfs

# Add your key to .env.local:
# RENDERPDFS_KEY=rpdf_your_key

2. Convert HTML to PDF

The simplest case: send an HTML string, get back a PDF binary. Anything Chromium renders works — Flexbox, Grid, web fonts, SVG, JavaScript.

Route Handler — HTML → PDFtypescript
// app/api/invoice/route.ts
import { RenderPDFs } from "renderpdfs";

const client = new RenderPDFs({ apiKey: process.env.RENDERPDFS_KEY! });

export async function GET() {
  const pdf = await client.generate({
    html: "<h1>Invoice</h1><p>Generated from Next.js</p>",
  });

  return new Response(pdf, {
    headers: {
      "Content-Type": "application/pdf",
      "Content-Disposition": 'attachment; filename="invoice.pdf"',
    },
  });
}

3. Convert a URL to PDF

Pass url instead of html and RenderPDFs fetches the page, waits for JS, and snapshots it. Useful for archiving dashboards, public pages, or invoices served from your app.

Snapshot one of your own pagestypescript
// app/api/snapshot/[id]/route.ts
import { RenderPDFs } from "renderpdfs";

const client = new RenderPDFs({ apiKey: process.env.RENDERPDFS_KEY! });

export async function GET(
  _req: Request,
  { params }: { params: Promise<{ id: string }> }
) {
  const { id } = await params;
  const pdf = await client.generate({
    url: `${process.env.NEXT_PUBLIC_APP_URL}/invoices/${id}/print`,
    options: { format: "A4", printBackground: true },
  });
  return new Response(pdf, { headers: { "Content-Type": "application/pdf" } });
}

4. Use a built-in template

Skip the design work. RenderPDFs ships six battle-tested templates — invoice, receipt, report, contract, certificate, offer_letter. Send JSON, get a styled PDF.

Server Action — built-in templatetypescript
// app/actions/generate-invoice.ts
"use server";
import { RenderPDFs } from "renderpdfs";

const client = new RenderPDFs({ apiKey: process.env.RENDERPDFS_KEY! });

export async function generateInvoice(invoice: Invoice) {
  const { url } = await client.generate({
    template: "invoice",
    data: invoice,
    store: true,   // returns { url, expires_in }
  });
  return url;
}

5. Custom paper, margins, headers

Control page format, orientation, margins, and running headers/footers via the options object. All standard Chromium PDF settings are supported.

Streaming PDF download to the browsertypescript
// app/invoices/[id]/pdf/route.ts
export async function GET(
  _req: Request,
  { params }: { params: Promise<{ id: string }> }
) {
  const { id } = await params;
  const invoice = await db.invoice.findUnique({ where: { id } });

  const pdf = await client.generate({
    template: "invoice",
    data: invoice,
    options: {
      format: "A4",
      margin: { top: "20mm", bottom: "20mm", left: "15mm", right: "15mm" },
    },
  });

  return new Response(pdf, {
    headers: {
      "Content-Type": "application/pdf",
      "Content-Disposition": `inline; filename="invoice-${invoice.number}.pdf"`,
      "Cache-Control": "private, max-age=300",
    },
  });
}

6. Store the PDF and share a link

For emailable links or webhook payloads, set store: true in the body. The response becomes { url, expires_in } — the PDF is hosted on our CDN for 24 hours by default.

Background job: store and emailtypescript
// app/api/webhooks/order-paid/route.ts
import { RenderPDFs } from "renderpdfs";
import { sendEmail } from "@/lib/email";

const client = new RenderPDFs({ apiKey: process.env.RENDERPDFS_KEY! });

export async function POST(req: Request) {
  const order = await req.json();

  const { url } = await client.generate({
    template: "receipt",
    data: order,
    store: true,
  });

  await sendEmail({
    to: order.customer_email,
    subject: "Your receipt",
    html: `<a href="${url}">Download your receipt</a>`,
  });

  return Response.json({ ok: true });
}

7. Notes & gotchas

Keep it server-side

Always call RenderPDFs from a Route Handler, Server Action, or Server Component — never from a Client Component. Your API key must stay out of the browser bundle.

Response format

By default the endpoint streams back the raw PDF binary (Content-Type: application/pdf). Set `store: true` in the body and the response becomes { url, expires_in } — useful for emailing links or attaching to webhooks.

Handling errors

Non-2xx responses return JSON: { error: string }. The most common cases are 401 (bad API key), 402 (over plan quota), and 422 (invalid HTML or URL). Always parse the error body before retrying.

Other languages

Generate your first PDF in 60 seconds

100 free PDFs per month. No credit card. HTML, Markdown, URLs, templates, MCP — all included.