Skip to content

HTML to PDF Converter

Paste HTML or upload a .html file, get a PDF. Pick the privacy-first local raster mode, or the server mode for real selectable text.

Two modesLocal runs 100% in your browser. Server (selected in the widget) uploads over TLS, auto-deleted in 10 minutes.

Learn more
Rendering mode

Paste HTML markup below — only inline CSS/styles will be applied.

External CSS/JS links won't load — inline styles work best. Web fonts must use data URIs or @font-face with a fetchable URL.

Your HTML never leaves your browser. Rendering uses html2canvas + jsPDF locally. JavaScript inside the HTML won't execute — only static layout is captured. Output text is image-based; switch to Server mode for selectable text.

About this tool

Sometimes you just want a PDF of an HTML document — an invoice template you built, a blog post saved as HTML, a styled email signature you want to share, a code-generated receipt page. This tool offers two clearly labeled rendering paths so you can pick the right one for the job. The default Local (raster) mode runs entirely in your browser: html2canvas captures the rendered HTML to a canvas, jsPDF wraps each page-tall slice into a PDF, and nothing leaves your device. Output text is image-based — not selectable, not searchable, not accessible — but the whole conversion is private and fast. The opt-in Server (text-layer) mode uploads the HTML to our server, where headless Chromium renders it just like Chrome's Print > Save as PDF and returns a real text-layer PDF. Output is selectable, searchable, screen-reader accessible, and honours @page CSS and CSS page-break rules. The server auto-deletes everything within 10 minutes; nothing is logged. The how-to and FAQ below cover when to pick each mode and the common gotchas (images not loading, blurry output on retina screens, page break behaviour).

How to html to pdf converter

  1. Pick a rendering mode

    Local (raster) runs in your browser — privacy-first but text is not selectable. Server (text-layer) uploads to headless Chromium for a real text-layer PDF. The tradeoff is shown next to each option.

  2. Paste or upload HTML

    Paste raw HTML into the textarea, or drop a .html file. A sample document loads by default so you can see the flow before swapping in your own.

  3. Pick a paper size and orientation

    A4 or Letter, portrait or landscape. Margin in millimeters is adjustable for breathing room around the content.

  4. Click Convert

    Local mode finishes in about 2-3 seconds for a 1-page document. Server mode adds an upload step and runs Chromium server-side in roughly 3-8 seconds total.

  5. Download the PDF

    The output is a paginated PDF based on the paper size you chose. Server-mode output has a filename derived from the HTML <title> tag.

Why use this tool

You hand-built an invoice or a quote in HTML because Word and Google Docs are overkill for one page and now you need a PDF to email a client. You have an email signature with images and styled text and you want a PDF version to include in a packet. You wrote a styled HTML report for an internal stakeholder who insisted on "a PDF, not a link." You generated an HTML document from a script (a daily summary, a customer-facing receipt, a code-generated report) and need a PDF version for archiving. You are testing how a printed version of your web page will look without running an actual browser print job. You built a styled CV in HTML/CSS because you wanted control over typography that Word does not give you. You are creating a one-off branded handout. The Chrome "Save as PDF" flow inside Print is the closest equivalent, but this page lets you do it from inside any browser without opening the print dialog, and works on input you have not loaded as a web page.

Features

Two modes, honest tradeoffs

Pick Local (raster) when privacy matters most — your HTML never leaves your device, conversion runs in your browser via html2canvas + jsPDF, and the output is image-per-page. Pick Server (text-layer) when you need selectable, searchable, accessible text in the PDF — uploads to our server, renders with headless Chromium just like Chrome's Print > Save as PDF, returns a real vector PDF with embedded fonts. Both modes are equally prominent; the labels say exactly what each one does in one sentence.

Real text-layer output (server mode)

The server-side path uses headless Chromium to render your HTML the same way Chrome would, then exports a true PDF with selectable text characters, embedded fonts, and vector graphics. You can highlight, copy, search, screen-read, and OCR-skip the result. CSS @page rules and page-break-before/page-break-after work as you would expect. This is the differentiator over every browser-only HTML-to-PDF tool, which can only produce rasterized output.

Privacy-first local mode

Local mode is fully client-side: html2canvas captures the rendered HTML to a canvas, jsPDF wraps the canvas into PDF pages, nothing touches the network. Useful when the HTML contains personal data (a quote with client details, a signed agreement template, a receipt with a name and amount) you do not want to upload to a converter service. The downside is that external resources (CSS files via URL, web fonts from CDNs, images by URL) do not load — inline what you need or use server mode.

Paste or file upload

Two input modes for two workflows. Paste raw HTML when you have a snippet (an email template, a code-generated document, a chunk of styled content from another app). Upload a saved .html file when you have the full document on disk (a page you saved from a browser with Ctrl+S, an exported report from a script, a static site build output). Both feed into the same conversion pipeline so the output is identical regardless of input method.

Privacy & security

This tool offers two modes with different privacy guarantees, and the mode you pick inside the widget determines what happens to your data. In Local mode the conversion runs entirely in your browser — your input is processed by JavaScript on your device and the result is downloaded straight to your filesystem, with zero network requests to our servers. You can verify this in your browser's Network tab. In Server mode the input is uploaded over HTTPS to our server, processed with a headless renderer there, and returned to you; the uploaded input and the generated output are automatically deleted within 10 minutes and we keep no copies. We do not inspect file contents in either mode, do not log them, and do not share them with third parties. If a stronger privacy guarantee matters, stick to Local mode — the choice is yours and is shown clearly inside the widget.

Frequently asked questions

Why offer both modes — what is the tradeoff?
Local (raster) mode runs entirely in your browser using html2canvas + jsPDF. The HTML never leaves your device, the conversion is fast, but the output is image-per-page: text is not selectable, not searchable, and not accessible to screen readers. Server (text-layer) mode uploads the HTML to our server where headless Chromium renders it the same way Chrome's Print > Save as PDF would, then returns a vector PDF with a real text layer, embedded fonts, and proper @page / page-break support. The server deletes the input and output within 10 minutes and logs no content. Use Local mode when privacy matters most or you cannot upload the markup. Use Server mode when you need selectable text, search, accessibility, or correct CSS page breaks. Both modes are equally prominent in the UI; the choice is yours.
Will my CSS look right in the PDF?
Basic CSS — colors, fonts already loaded in the browser, layouts (flexbox, grid), tables, borders, backgrounds — all render correctly because the HTML is captured after the browser has done the actual layout pass. The trip-ups are external resources: CSS files loaded by URL do not get fetched if the rendering context blocks them, web fonts from Google Fonts may not load if not pre-cached, and images loaded by URL will be missing unless you inline them as data URLs or base64. Server mode handles external resources without these restrictions because Chromium has full network access during the render. For pixel-perfect output in local mode, inline everything.
Why are my images not showing in the PDF?
Because the rendering context is sandboxed against arbitrary external fetches for security. Images referenced as <img src="https://..."> may not load. The fix is to inline images as data URLs: convert your images to base64 and use <img src="data:image/png;base64,..."> instead. For local files referenced as <img src="./photo.jpg">, those will not work because the rendering context has no path resolution. Either inline as base64 or skip the images.
Can I send a URL instead of pasting HTML?
Not directly. The tool needs the HTML content to render, and fetching arbitrary URLs from the browser is blocked by CORS for most sites. The workaround is to save the page first: in Chrome/Firefox, Ctrl+S or Cmd+S, choose "Webpage, Complete" or "Webpage, HTML Only", and then upload that saved file. The HTML-only version often works better because it avoids the chaotic _files directory and the asset references that come with it.
Will JavaScript run before the capture?
Yes, with limits. The HTML renders and any inline <script> tags execute. So if your HTML has JS that builds the DOM dynamically (a templated email, a JS-rendered chart with data inlined), that runs and the result is what gets captured. The capture happens shortly after load, so very long-running async operations (fetching from an API, animating in over several seconds) may not complete in time — for those, render the document statically first by capturing the final DOM state and saving as plain HTML.
How does multi-page output work?
html2canvas renders the entire HTML document into one tall canvas (effectively a tall screenshot). Then jsPDF slices that canvas at page-height boundaries (based on the A4 or Letter size you chose) and adds each slice as a page in the PDF. The cut happens at fixed pixel heights, so it can split lines of text awkwardly across pages — there is no semantic page-break logic. For invoices or reports where clean page breaks matter, use Chrome's Print > Save as PDF instead and add @page CSS rules to control breaks.
Why is the output blurry?
Probably because html2canvas captured at the default pixel ratio. If you are on a Retina display the captured canvas may be scaled at 1x rather than 2x or 3x, leading to softer output when stretched to PDF page dimensions. Try a smaller page size, or pre-scale the HTML by setting a larger font size and using A4 — the captured canvas resolution then maps closer to print DPI. For genuinely sharp output, server-side headless Chrome with print-CSS produces better results.
Does this support page breaks via CSS?
Server (text-layer) mode does — headless Chromium honours @page rules, page-break-before, page-break-after, and break-inside: avoid the same way Chrome's Print > Save as PDF does. Local (raster) mode does not: the pagination is done by slicing the rendered canvas at fixed pixel heights, which ignores CSS page-break semantics. If you need clean breaks between sections (a long invoice where each item must not split across pages, a report where chapters start fresh), switch to Server mode.
Can I use web fonts (Google Fonts, etc.)?
Only if they are already loaded in your browser when the conversion runs. Web fonts referenced via @import or @font-face URLs to Google's CDN may not load in the sandboxed context. The workaround is to load the fonts in the parent page first (the converter page itself) so the browser has them cached, or inline the font files as data URLs in your CSS. For most non-decorative use, sticking to system fonts (Arial, Helvetica, Georgia, Courier New) is the most reliable path.
What is the maximum HTML size?
There is no hard limit on input HTML size, but very long pages (50+ A4 pages worth of content) start to strain browser memory because html2canvas has to render the whole thing to one giant canvas before slicing. Practical ceiling is around 30-40 A4 pages of content. Beyond that, split the HTML into chunks, convert each separately, and merge the resulting PDFs with the merge tool.
Is my HTML uploaded anywhere?
Depends on the mode. In Local (raster) mode — the default — the conversion runs entirely in your browser using html2canvas and jsPDF. Your HTML, inlined images, and the resulting PDF never leave your device; the Network tab will confirm no outgoing requests are made. In Server (text-layer) mode, the HTML is uploaded over HTTPS to our server in Germany, rendered with headless Chromium, and both the input and output are deleted within 10 minutes. Nothing is logged beyond an operation status code. Pick Local mode when the HTML contains client data, financial information, or anything that should not touch a third party.
What is the difference between this tool and Chrome's Print > Save as PDF?
Chrome's print-to-PDF is the gold standard for HTML rendering: it uses Chrome's full layout engine, respects @page CSS, handles page breaks semantically, embeds web fonts properly, and produces text-selectable PDFs with vector text. Our Server (text-layer) mode does effectively the same thing — it runs headless Chromium server-side and produces the same kind of vector PDF — so for inputs without sensitive content you get equivalent output quality without leaving the tool. Use Chrome's print flow for one-off conversions of a page already open in your browser. Use our Server mode when you have HTML as a string or a file you want to convert programmatically.
Why does the PDF text not get selected when I try to copy it?
You are probably in Local (raster) mode. The local path rasterizes HTML to a canvas image and jsPDF wraps that image into PDF pages — so the resulting PDF contains images of text rather than actual text characters, and you cannot select or search the text. To get a selectable text layer, switch to Server (text-layer) mode at the top of the tool. The server path uses headless Chromium and produces real vector PDFs with embedded fonts and selectable, searchable, accessible text.
What HTML features specifically do NOT work?
Things that need network requests after rendering: external CSS files, web fonts loaded from CDNs that the browser has not pre-cached, images referenced by URL. Things that need ongoing JS execution: animations, async-loaded content, anything that depends on the page being viewed for more than a few seconds. CSS that depends on the viewport size (responsive layouts) may render at the rendering-container's size rather than the paper size. For most static document content, none of these are issues; for app-like HTML, they often are.