I needed PDF copies of invoice pages for bookkeeping. The usual answer is Puppeteer, which means installing Chromium on your server, keeping it patched, and giving it a few hundred MB of RAM. On a small VPS that hurts. So I put headless Chromium behind a plain HTTP endpoint and now PDF generation is one GET request.
curl --get "https://snappdf.dedyn.io:8444/v1/pdf" \
--data-urlencode "url=https://en.wikipedia.org/wiki/PDF" \
--data-urlencode "format=A4" \
-o page.pdf
That's it. --data-urlencode handles the nested URL for you, and page.pdf comes back as a real Chromium print render, so CSS, web fonts, and layout all survive.
A few query params cover the cases I actually hit:
-
formatfor paper size (A4,Letter, and the other common ones) -
landscape=truefor wide tables -
scalefrom 0.1 to 2 when a page is too cramped or too small at 100% -
background=falseto drop background colors for cheaper printing -
waitForSelector=#invoice-totalwhen the page renders client-side and you need to wait for a specific element before snapshotting
The waitForSelector one matters more than it looks. Most URL-to-PDF converters screenshot React apps before the data loads and you get a PDF of a spinner.
I use it from a cron job that archives receipts, but it works anywhere you can make an HTTP request: a Zapier webhook, a GitHub Action, a fetch() in a route handler.
Code is on GitHub if you'd rather self-host it: https://github.com/clause-netizen/snappdf-api
If you try the demo endpoint and something breaks, tell me. It runs on a small box and I'd like to know where the limits are.
Top comments (0)