Getting started

Generate PDFs from HTML templates.

A Next.js service that renders modular templates through Puppeteer. Send a JSON payload, get a styled PDF back. Built-in Sentry tagging scopes errors by project.


Components are composed by passing a blocks array. Themes are plain CSS strings that override CSS custom properties used by every component.

Heads up. Generation runs server-side through Puppeteer. Expect 600 to 1200ms cold-start, ~120ms warm.

Install & run

Clone the repo, install dependencies, and start the dev server. The endpoint comes up at /api/template-pdf.

Prerequisites

  • Node 20 LTS or later

Local development

terminal
# Clone the repo
git clone https://github.com/FluxBelgium/pdf-generator_next
cd pdf-generator_next

# Install & run
npm install
npm run dev  # → http://localhost:3000

API request

POST to /api/template-pdf with a JSON body. The response is a binary PDF stream.

Endpoint

POST /api/template-pdf
curl -X POST https://pdf-generator.3dconfig.io/api/template-pdf \
  -H "Content-Type: application/json" \
  -d '{
    "appID": "1234567890",
    "templateId": "invoice",
    "theme": "@import url(https://fonts.googleapis.com/css2?family=Manrope:wght@200..800); :root { --primary: #436414; --font-primary: Manrope, sans-serif; }",
    "data": {
      "header": {
        "name": "Flux",
        "email": "contact@flux.be",
        "phone": "0485 40 26 71",
        "address": "Frankrijklei 67, 2000 Antwerpen",
        "logo": "https://flux.be/wp-content/uploads/2025/06/flux_logo_navy.svg"
      },
      "blocks": [
        {
          "type": "table",
          "data": {
            "title": "Items",
            "description": "These are the items that you have purchased",
            "header": ["Description", "Quantity", "Price", "Total"],
            "items": [["Website Design", 1, 500, 500], ["Hosting", 1, 100, 100]],
            "footer": ["", "", "Total", 600]
          }
        }
      ],
      "footer": {
        "address": "Frankrijklei 67, 2000 Antwerpen",
        "footerText": "Thank you for your business!"
      }
    }
  }' \
  --output ~/Downloads/invoice.pdf

Request body

FieldTypeRequiredDescription
appIDstringnoTenant identifier. Recommended for Sentry error tagging per project.
templateIdstringyesOne of the registered templates (e.g. invoice).
themestringnoRaw CSS defining --primary, font, radius, etc.
dataobjectyesPayload consumed by the template.

Response

200 OK with Content-Type: application/pdf. On failure: 400 for validation errors, 503 if the browser pool is exhausted, 500 for generation failures. All return a JSON error body.

Themes

Plain CSS strings. Set your brand color, font, and border radius. It cascades into every template component automatically.

CSS custom properties

theme.css
@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@200..800');

:root {
  /* Brand color */
  --primary: rgb(25, 32, 59);
  --primary-light: rgb(210, 220, 246);
  --primary-lightest: rgb(227, 234, 250);
  --primary-dark: rgb(10, 13, 24);

  /* Neutral grays */
  --gray: #474747;
  --gray-light: #e5e5e5;
  --gray-lightest: #f5f5f5;

  /* Typography & shape */
  --font-primary: "Manrope", sans-serif;
  --border-radius: 0.25rem;
}

Presets

Pick a preset, then generate a sample PDF to see it in action.

Available templates

View invoice template

Error tracking

Pass appID on any request and it flows into Sentry, so you can filter and route issues per project without a separate tenant.

  • Tagging: all errors are tagged with the appID on capture.
  • Filtering: use Sentry's tags:appID query to isolate a client.
  • Routing: wire alerts per appID to the right team.