Render an HTML string (or URL) into a PDF document
Run
wippy run kickside/html2pdfhtml2pdf
Render an HTML document into a PDF. The source is an HTML string or an http(s)
URL (downloaded automatically); output is the PDF as raw bytes.
API
local html2pdf = require("html2pdf")
local pdf, err = html2pdf.render({ html = "<h1>Hello</h1>" })
if err ~= nil then
return nil, err -- err.kind / err.message / tostring(err)
end
html2pdf.render(request [, options]) -> pdf, err
request— a table with exactly one source:{ html = "<…>" }— a UTF-8 HTML document string, or{ url = "https://…" }— anhttp(s)URL, downloaded automatically.
options— an optional table (unknown keys are rejected):page_size—"A4"(default),"Letter","Legal","A3","A5".landscape— boolean, defaults tofalse.margin_mm— page margin in millimetres, a non-negative number, defaults to10.
pdf— the rendered document as PDF bytes (a binary Lua string), ornilon failure.err—nilon success, otherwise a structured error.
html2pdf.new(runtime) -> module
Advanced: build an instance with injected runtime dependencies
({ funcs?, http_client? }). See RFC 0001.
Errors
Every failure returns a structured error table with message, kind, and
retryable. kind is one of invalid_input, download_failed, render_failed,
internal. tostring(err) and string concatenation yield the message.
Limits and safety
- Inputs (the HTML string or downloaded body) are capped at 128 MiB.
- URL fetches use an http(s)-only scheme allow-list, a 30s timeout, and a download size cap; private-IP targets are blocked by the runtime.
Rendering engine
HTML and CSS are rendered by an embedded
litehtml engine, with PDF output produced by
libharu, both compiled into a single
wasm32-wasip2 component. The engine supports real HTML and CSS including flexbox,
tables, backgrounds, borders, and list markers.
- Fonts — DejaVu LGC (Sans, Serif, Mono; regular/bold/italic) are embedded in the
component, so
sans-serif,serifandmonospacerender out of the box. Text is UTF-8, so Latin accents and common symbols (e.g.á ç ã é € —) render correctly. - Images —
data:URIs in JPEG are drawn; other formats (including PNG) and remotehttp(s)image references are not resolved. - Not supported — JavaScript, CSS Grid, and full browser-grade CSS fidelity. This module targets document-grade HTML/CSS (reports, invoices, certificates), not arbitrary web pages.
- Pagination — a single page is produced per call; content taller than the page is clipped.