Hey everyone! Today I'd like to introduce an open-source library called dom-to-vector-pdf. It exports rendered DOM elements directly as vector PDFs, entirely in the browser — no server required.
Live Demo
Want to try it before reading? Check out the online demo.
Documentation
Full configuration options, lifecycle hooks, and more can be found in the official docs: dom-to-vector-pdf.xzboss.cn
What Is a Vector PDF?
The most common approach to exporting a web page as PDF is via canvas (e.g. html2canvas), which essentially takes a screenshot. The result is a rasterized image: it blurs when zoomed in, text cannot be selected, and file sizes tend to be large.
A vector PDF is different — text, shapes, and paths are all stored as vectors. It stays sharp at any zoom level, text is selectable and copyable, and print quality is noticeably better. For reports, contracts, and document-style pages, vector PDF is the right choice.
Basic Usage
Install:
npm install dom-to-vector-pdf
Usage:
import fontTTF from '@/assets/your-font.ttf'
import vectorInstance from 'dom-to-vector-pdf'
export const exportToPDF = (selector, filename) => {
vectorInstance.registerFont([
{ font: fontTTF, fontWeight: '400', fontStyle: 'normal' },
{ font: fontTTF, fontWeight: '700', fontStyle: 'normal' },
])
vectorInstance.exportPDF({ selector, filename })
}
Call exportToPDF('#my-content', 'report.pdf') to export the target DOM area as a PDF file.
How It Works
The core pipeline is: DOM → SVG → PDF.
- dom-to-svg: Serializes the DOM into SVG, preserving styles, layout, and font information
- svg2pdf.js: Renders the SVG as vector content onto the jsPDF canvas
- jsPDF: Generates and downloads the final PDF file
The SVG serialization step adds a small overhead, but performance is generally fine for most pages. If export is slow, the font file size is usually the culprit — subsetting the font is the most effective optimization.
FAQ
Non-Latin characters appear garbled — how do I fix it?
Characters like Chinese require a font to be registered manually, otherwise they will not render correctly. Pass a TTF font file to registerFont (supports both local import and online CDN URLs).
Things to watch out for:
- Only TTF format is currently supported
- Font files can be subsetted — a common Chinese character set (3500 chars) can be trimmed down to under 1 MB, significantly reducing file size and export time
- ⚠️ Many online subsetting tools strip the space character, which causes rendering failures. It's recommended to use a command-line tool like
pyftsubsetto subset fonts, and make sure to include the space and newline characters explicitly
If you run into any issues or have feature requests, feel free to open an Issue or Pull Request on GitHub.
Top comments (0)