Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
The most reliable way to turn HTML into a PDF on a server is to render it with a headless Chromium browser. For a ready-made API, send your template and assets to Gotenberg’s /forms/chromium/convert/html endpoint, or submit a deployed page to /forms/chromium/convert/url. If you need complete control over the rendering process, build a small service around Playwright’s Chromium-only page.pdf() method.
Choose the input that matches your document
There are two fundamentally different jobs:
- Local HTML and assets: your application owns the template, images, fonts and stylesheets. Upload them as multipart form data.
- A deployed URL: the renderer opens a page over HTTP, executes JavaScript and waits for dynamic content before printing it.
Both approaches use a browser engine, so modern CSS, web fonts, client-side charts and single-page applications can be rendered much more faithfully than a parser that only understands static HTML.
Use Gotenberg as a self-hosted PDF API
Gotenberg packages headless Chromium behind an HTTP API. Its HTML route “converts an index.html file (and optional assets) to PDF using Headless Chromium.” You run the service yourself (commonly as a Docker container), then call it from your application.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchConvert a local template
- Create a complete document named
index.html. Use relative paths for images, CSS and fonts that you will upload in the same request. - Send the files as multipart form data to
/forms/chromium/convert/html. - Write the binary response to a file or stream it to the client with
Content-Type: application/pdf.
curl --request POST http://localhost:3000/forms/chromium/convert/html
--form files=@/path/to/index.html
--form files=@/path/to/styles.css
--form files=@/path/to/logo.png
-o invoice.pdf
The uploaded HTML must be named index.html; additional files retain their filenames so references such as <link rel="stylesheet" href="styles.css"> and <img src="logo.png"> resolve correctly.
#1 Best Overall
- PORTABLE SCANNER FOR USE ON-THE-GO — The fastest and lightest mobile single-sheet-fed compact document scanner in its class¹
- QUICK DOCUMENT SCANNING ― This Epson ultra-fast scanner scans a single page as quickly as 5.5 seconds²; Windows and Mac compatible
- VERSATILE PAPER HANDLING ― Portable scanner scans documents up to 8.5 x 72 in; Also easily digitizes receipts and ID cards to make accounting, bookkeeping, and organizing simpler
- INTUITIVE, HIGH-SPEED SOFTWARE — Epson ScanSmart Software³ is a smart tool allowing you to easily scan, review, and save; Stay organized easily with the help of this Epson scanner
- EASY SETUP — USB-powered connect to your computer for quick and simple scanning; No batteries or external power supply required to operate portable document scanner; Standard Connectivity: USB 2.0
Render a deployed page
Use /forms/chromium/convert/url when the source is already hosted. This route is designed for JavaScript-heavy pages, SPAs and content that is assembled after the initial response.
curl --request POST http://localhost:3000/forms/chromium/convert/url
--form url=https://example.com/report
--form waitForExpression='window.reportReady === true'
-o report.pdf
A fixed delay can work for simple pages, but a signal such as waitForExpression is more deterministic when your application fetches data or draws charts asynchronously. Set the signal in your page only after all content required in the PDF is ready.
Control paper, pagination and appearance
Paper size and CSS
Define document geometry in CSS when the template should control it:
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minute@page {
size: A4;
margin: 18mm 15mm 20mm;
}
.invoice-table { break-inside: avoid; }
.page-break { break-before: always; }
When using CSS-defined sizes, enable Gotenberg’s preferCssPageSize. Otherwise provide paper width and height through the request fields. The Chromium options also cover margins, orientation and scale.
Backgrounds and print media
Set printBackground=true when colored sections, gradients or background images are part of the design. Remember that browser printing normally uses print media styles; put print-specific rules in @media print and test them separately from screen styles.
Page breaks and long content
Use semantic break rules rather than inserting dozens of empty elements:
Rank #2
- FAST SPEEDS - Scans color and black and white documents a blazing speed up to 16ppm (1). Color scanning won’t slow you down as the color scan speed is the same as the black and white scan speed.
- ULTRA COMPACT – At less than 1 foot in length and only about 1. 5lbs in weight you can fit this device virtually anywhere (a bag, a purse, even a pocket).
- READY WHENEVER YOU ARE – The DS-640 mobile scanner is powered via an included micro USB 3. 0 cable allowing you to use it even where there is no outlet available. Plug it into you PC or laptop and you are ready to scan.
- WORKS YOUR WAY – Use the Brother free iPrint&Scan desktop app for scanning to multiple “Scan-to” destinations like PC, Network, cloud services, Email and OCR. (2) Supports Windows, Mac and Linux and TWAIN/WIA for PC/ICA for Mac/SANE drivers. (3)
- OPTIMIZE IMAGES AND TEXT – Automatic color detection/adjustment, image rotation (PC only), bleed through prevention/background removal, text enhancement, color drop to enhance scans. Software suite includes document management and OCR software. (4)
break-before: alwaysstarts a new page for a chapter or cover.break-after: alwaysends a section deliberately.break-inside: avoidkeeps cards, table rows or signature blocks together when possible.
No browser can keep an item together if it is taller than a page. Design oversized tables and images to wrap or scale, and verify the result with representative data.
Recommended Free Tools
Make conversions reliable in production
Choose explicit failure behavior
A PDF can be technically produced while missing an image, font or API response. Configure Gotenberg’s failure controls according to your needs:
failOnHttpStatusCodesrejects navigation responses with selected HTTP errors.failOnResourceHttpStatusCodesrejects failed subresources such as stylesheets or images.failOnResourceLoadingFailedtreats browser resource-loading failures as conversion errors.
Strict settings are appropriate for invoices and regulated reports; lenient settings may be preferable for a public page where one advertising resource should not cancel the entire document.
Restrict outbound access
URL rendering can cause the browser to call every origin referenced by the page. Use Gotenberg’s outbound URL filtering to allow only your application, asset host and required APIs. This reduces accidental data exfiltration and server-side request risks.
Bound time and observe jobs
Set a maximum conversion duration in your worker or reverse proxy. Log the source URL or document ID, wait condition, browser errors, response status and elapsed time. A bounded timeout prevents a page waiting forever for a network request from consuming a renderer.
Isolate Chromium
Run the renderer in a container or separate service account with least-privilege network and filesystem access. Treat uploaded HTML and remote URLs as untrusted input. Do not expose the conversion endpoint directly to the public Internet without authentication, rate limiting and request-size limits.
Rank #3
- FAST DOCUMENT SCANNING — Document scanner with feeder allows you to speed through stacks with a 50-sheet Auto Document Feeder (ADF); Efficient office scanner to help you scan more productively
- INTUITIVE, HIGH-SPEED SOFTWARE — Quickly scan with this desktop document scanner; Epson ScanSmart Software lets you easily preview scans, email files, upload to the cloud, and more; Plus, automatic file naming saves even more time
- SEAMLESS INTEGRATION — Easily incorporate your data into most document management software with the included TWAIN driver; Office document scanner integrates seamlessly with business workflows
- EASY SHARING — Duplex scanner allows you to scan straight to email or popular cloud storage2 services like Dropbox, Evernote, Google Drive, and OneDrive for simple storage and sharing
- SIMPLE FILE MANAGEMENT — Scanner allows the creation of searchable PDFs with Optical Character Recognition (OCR) and convert scans to editable Word or Excel files effortlessly; Designed for home and office document scanning
Accessibility, archiving and document controls
Tagged PDFs and outlines
Use real headings (h1 through h6), lists, tables with header cells and meaningful alternative text. Gotenberg’s generateDocumentOutline option builds bookmarks from semantic headings and also enables tagged PDF generation.
PDF/A and PDF/UA
For archival or accessibility requirements, Gotenberg documents PDF/A and PDF/UA post-processing options. Validate the resulting file with the compliance tool required by your organization; browser output alone does not guarantee conformance.
Metadata, encryption and page selection
Document controls include metadata, page ranges, watermarks, stamps and encryption. PDF/A and encryption are mutually exclusive. Some post-processing modes can rasterize table cells, so inspect selectable text and accessibility after enabling them.
Build your own API with Playwright
Playwright is useful when you need application-specific authentication, custom readiness logic or a renderer embedded in your existing service. PDF generation is Chromium-only.
Minimal Node.js service function
import { chromium } from 'playwright';
export async function htmlToPdf(url) {
const browser = await chromium.launch({ headless: true });
try {
const page = await browser.newPage({
viewport: { width: 1280, height: 900 },
deviceScaleFactor: 1
});
await page.goto(url, { waitUntil: 'networkidle', timeout: 60000 });
await page.emulateMedia({ media: 'print' });
await page.waitForFunction(() => window.reportReady === true, null, { timeout: 30000 }).catch(() => {});
return await page.pdf({
format: 'A4',
printBackground: true,
preferCSSPageSize: true,
margin: { top: '18mm', right: '15mm', bottom: '20mm', left: '15mm' }
});
} finally {
await browser.close();
}
}
Playwright’s API reference specifies that to generate a PDF using screen media, call page.emulateMedia() before page.pdf(). The example uses print media, which is the browser default for PDF output; switch to { media: 'screen' } when the screen stylesheet is the intended design.
Serve the bytes safely
In an HTTP handler, set Content-Type: application/pdf, a bounded Content-Length when known, and a Content-Disposition filename. Stream or spool large files instead of retaining many buffers in memory. Reuse a controlled browser process where your workload permits, but create isolated browser contexts per request so cookies and local storage cannot leak between users.
Rank #4
- Scanner type: Document
- Connectivity technology: USB
- With Auto Scan Mode, the scanner automatically detects what you're scanning
- Digitize documents and images
Gotenberg or Playwright?
| Requirement | Gotenberg | Playwright service |
|---|---|---|
| Local HTML plus assets | Multipart upload to the documented HTML route | Write files or serve them from a testable origin, then navigate |
| Remote URL and JavaScript | Dedicated URL route with wait controls | Full control over navigation and readiness code |
| Paper, margins and backgrounds | Request fields plus CSS | page.pdf() options plus CSS |
| Outlines, PDF/A, PDF/UA and post-processing | Documented built-in controls | You must add and maintain supporting tooling |
| Operational burden | Operate a separate PDF API and Chromium workers | Maintain browser lifecycle, queues, isolation and API code |
| Deployment model | Self-hosted service | Self-hosted application component |
Common failures and fixes
The PDF is blank
Usually the page was printed before client-side rendering finished. Add a deterministic readiness expression, wait for a specific selector, or increase a bounded delay. Confirm that the page does not require a login cookie unavailable to the renderer.
Images or fonts are missing
For local conversion, upload every asset and use matching relative filenames. For URL conversion, check network access, HTTPS certificate validity, CORS behavior and resource status codes. Strict resource-failure settings will reveal the first failed dependency.
Colors or backgrounds differ
Enable printBackground=true, inspect @media print rules and confirm that CSS colors are not being overridden by a print stylesheet.
Content is cut off or overlaps
Check CSS page size, margins, scale and fixed-position elements. Replace fragile pixel heights with flow layout, add explicit break rules and test the longest realistic table or paragraph.
The request hangs
Look for a page that never reaches network idle because of analytics or streaming connections. Prefer a readiness expression, block unnecessary requests, and enforce a conversion timeout with diagnostic logging.
Compliance output is unexpected
Validate tagged structure, outlines, selectable text and metadata after post-processing. Do not combine PDF/A with encryption, and verify whether a selected post-processor rasterized table cells.
Best Value
- OUR MOST ADVANCED SCANSNAP. Large touchscreen, fast 45ppm double-sided scanning, 100-sheet document feeder, Wi-Fi and USB connectivity, automatic optimizations, and support for cloud services. Upgraded replacement for the discontinued iX1600
- CUSTOMIZABLE. SHARABLE. Select personalized profiles from the touchscreen. Send to PC, Mac, mobile devices, and clouds. QUICK MENU lets you quickly scan-drag-drop to your favorite computer apps
- STABLE WIRELESS OR USB CONNECTION. Built-in Wi-Fi 6 for the fastest and most secure scanning. Connect to smart devices or cloud services without a computer. USB-C connection also available
- PHOTO AND DOCUMENT ORGANIZATION MADE EFFORTLESS. Easily manage, edit, and use scanned data from documents, receipts, photos, and business cards. Automatically optimize, name, and sort files
- AVOIDS PAPER JAMS AND DAMAGE. Features a brake roller system to feed paper smoothly, a multi-feed sensor that detects pages stuck together, and skew detection to prevent paper damage and data loss
Or skip the browser setup
ScreenshotNeo provides a hosted rendering API that can return PNG, JPEG, WebP or PDF from one GET request. It can render a URL, execute JavaScript and wait for a selector, delay or network idle; PDF requests also support paper size, margins, landscape mode and page ranges. Before capture, it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets, with controls to turn each step off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and whether the request was billed.
Request a PDF with cURL (see the ScreenshotNeo documentation for all parameters):
curl -G "https://api.screenshotneo.com/v1/shot"
-d access_key=YOUR_API_KEY
--data-urlencode url=https://example.com/report
-d format=pdf
-o report.pdf
The same endpoint can be called from Python or Node.js:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com/report", "format": "pdf"}, timeout=90)
r.raise_for_status()
open("report.pdf", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com/report', format: 'pdf' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
await Bun.write('report.pdf', res);
ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots, and every feature is included on every plan. Create a free ScreenshotNeo account.
Cost, throughput and scaling decisions
- Self-hosted predictable load: Gotenberg or Playwright keeps infrastructure under your control, but you pay in CPU, memory, browser updates, queueing and on-call work.
- Bursty or global traffic: a hosted API avoids maintaining Chromium workers; account for request limits, network latency and data-transfer policy.
- Throughput: queue conversions, cap concurrent browser pages, reuse browser processes carefully and measure the largest documents rather than relying on average pages.
- Caching: cache immutable inputs or generated PDFs with a content hash. Never reuse a cached document when authorization, tenant data or time-sensitive content can change.
Production checklist
- Use semantic HTML, explicit
@pagerules and tested break behavior. - Choose URL or multipart HTML input deliberately and verify every asset.
- Wait for a deterministic application-ready signal.
- Set paper, margins, orientation, scale and background behavior explicitly.
- Define HTTP and resource failure policy.
- Restrict outbound URLs and isolate untrusted rendering.
- Enforce timeouts, request-size limits, authentication and rate limits.
- Validate accessibility, archival profile, metadata and encryption choices.
- Test long tables, missing data, slow APIs, unusual fonts and failed images before release.
Frequently Asked Questions
Can an HTML-to-PDF API execute JavaScript?
Yes. Browser-based routes such as Gotenberg’s URL endpoint execute JavaScript, making them suitable for SPAs and dynamically rendered reports. A static HTML parser generally cannot reproduce that behavior.
Is Playwright PDF generation available in Firefox?
No. Playwright’s PDF export is Chromium-only.
Should I wait a fixed number of seconds before printing?
Use a page-specific readiness expression or selector when possible. A fixed delay is a fallback for pages without a reliable completion signal and can still be too short or unnecessarily slow.
Can I combine PDF/A with encryption in Gotenberg?
No. The documented options are mutually exclusive, so select the requirement that applies to your delivery or archival workflow.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

