Overview
HTML to PDF Converter is a full-stack SaaS application for converting HTML files into print-ready PDFs. The project supports both a free web interface for one-off conversions and a paid developer API for programmatic PDF generation.
What I Built
The web tool lets users drag and drop up to 10 HTML files, customise page format, orientation, margins, scale, and output mode, then download either a single PDF, a merged PDF, or a ZIP of separate PDFs.
The developer API adds account-based access, JWT API keys, usage tracking, Stripe subscriptions, and rate limiting. Developers can generate an API key from the dashboard and call a REST endpoint to convert HTML files from their own applications.
Technical Architecture
The app is built with Next.js App Router, React, TypeScript, MongoDB, NextAuth, Stripe, Upstash Redis, Vercel Blob, and Puppeteer. In development it uses full Puppeteer; in production it uses puppeteer-core with @sparticuz/chromium so Chromium can run inside Vercel's serverless environment.
The conversion flow is:
- User uploads one or more HTML files.
- The API validates file type, file count, and file size.
- Puppeteer renders each HTML document to PDF using the selected options.
- Multiple PDFs are either merged with
pdf-libor archived witharchiver. - The finished artifact is stored behind a session-based download route.
- The UI streams progress updates back to the user using server-sent events.
Sticking Points
Running Chromium on serverless infrastructure
The hardest part was making PDF rendering reliable in production. Local Puppeteer is straightforward, but deploying Chromium in a serverless environment requires a smaller runtime binary and launch flags that work within Vercel's constraints. I split the renderer so local development uses Puppeteer directly while production uses puppeteer-core and @sparticuz/chromium.
Giving users feedback during long conversions
Batch conversion can take several seconds, especially when users upload multiple complex HTML files. Instead of leaving the UI idle, the web route returns a streaming response and sends progress messages such as rendering, merging, archiving, and download preparation.
Supporting batch output cleanly
The app needed to handle three output cases: a normal single PDF, one merged PDF for multiple inputs, or a ZIP containing separate PDFs. I separated the PDF artifact creation logic from the route handler so the rendering, merging, zipping, and download metadata could be tested independently.
Protecting infrastructure costs
Because browser rendering is expensive, the app uses Upstash Redis rate limits for both the free web tool and the paid API. The public web interface is IP-limited, while the API is user-limited and tied to subscription state.
Result
The final product is a working HTML-to-PDF service with a free public converter, a paid API, account management, API key lifecycle controls, Stripe billing, and production-ready serverless rendering. It turns a deceptively simple feature into a complete SaaS workflow: upload, render, download, authenticate, bill, and protect the system from abuse.
The developer documentation is available at htmltopdfconverter.com.au/docs.
