Converting an HTML file to PDF is straightforward when the file is self-contained — all styles inline, no external images — and more nuanced when the file references external resources or relies on JavaScript. The right method depends on whether you need a quick one-off conversion, a repeatable automated process, or the ability to handle JavaScript-rendered content.
Method 1: print from a browser
Open the HTML file in Chrome, Edge, or Firefox by dragging it to the address bar or using File → Open. Then use File → Print → Save as PDF (or the print shortcut, Cmd+P on Mac, Ctrl+P on Windows). This uses the browser's own print renderer.
The result respects any print stylesheets the HTML file includes. If the file has no print stylesheet, the browser renders the screen layout scaled to fit the paper size. Navigation elements, if present in the HTML, are typically printed unless explicitly hidden with @media print rules.
This method works best for HTML files that were designed to be printed — reports, invoices, email templates with inline styles. It does not work for HTML files that rely on JavaScript to populate content, since the print dialog captures the current DOM state.
Method 2: a dedicated HTML-to-PDF converter
Filum's HTML to PDF tool accepts a local HTML file and renders it using a headless Chromium browser. Upload the file, press Convert, and the conversion runs server-side with a one-second delay to allow JavaScript to execute. The output is a PDF of what Chromium renders when it opens the file.
This method handles JavaScript-rendered content correctly, since Chromium runs the full browser engine before capturing the output. A React or Vue application that populates a DOM tree via JavaScript will render correctly in the output.
One important constraint: the server does not have access to your local file system. External resources referenced by URL — CDN-hosted fonts, images from an external server — load correctly. Resources referenced by relative path — a stylesheet in the same folder as your HTML, a local image — do not load, because those paths do not resolve from the server's perspective. To include local resources, either embed them inline (base64-encoded images, inline styles, inline SVG) or host them at an accessible URL.
The HTML file itself is processed server-side and immediately deleted after conversion. No account is required.
Method 3: command-line tools
For automated or batch conversion, command-line tools offer more control. wkhtmltopdf was the dominant tool for years and is still widely used, though its maintenance has slowed. It uses a Qt-based WebKit engine, which means it does not support modern CSS features that Chrome handles correctly.
Puppeteer and Playwright are Node.js libraries that drive a real Chromium browser. Both support generating PDFs via page.pdf(). This approach produces the same output as Chromium's print-to-PDF with full JavaScript support, CSS grid, CSS custom properties, and current web standards. The trade-off is a larger dependency footprint — Node.js and Chromium — and more configuration than a simple command.
Gotenberg is a Docker-based PDF generation service that wraps Chromium and LibreOffice. It provides a simple HTTP API and is the engine Filum uses internally for server-side HTML-to-PDF conversion.
Handling relative paths and self-contained HTML
The most reliable HTML-to-PDF conversion happens with self-contained HTML: styles in a <style> block, images as base64 data URIs, JavaScript inline. A self-contained file produces the same output regardless of where it is opened or which method is used.
If your HTML file references a separate stylesheet — <link rel="stylesheet" href="styles.css"> — that stylesheet must either be inlined before conversion or be available at a public URL. The same applies to images, fonts, and any other referenced assets.
Tools that convert from a local file path (wkhtmltopdf with a file:// URL, Puppeteer with page.goto('file://...')) can resolve relative paths. Tools that require an HTTP upload — including Filum and most online converters — cannot.