You convert a page to PDF in the browser, and the result looks soft when zoomed in. You cannot select text, Ctrl+F finds nothing, and the file is larger than you expect.
The cause
The html2pdf.js README states that it renders all content into an image, then places that image into a PDF. That means the text is not selectable or searchable, and the README notes it causes large file sizes. The underlying renderer, html2canvas, also draws to an HTML canvas, which has maximum height and width limits, so long pages can fail to render.
How to confirm
Open the PDF and try to select a sentence, or run a text extractor on it. If you get no text back, every page is an image.
The fix
Generate the PDF from the page layout instead of a screenshot of it. With headless Chromium through Puppeteer, page.pdf() produces the file using the print CSS media type:
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setContent(html, { waitUntil: 'networkidle0' });
const pdf = await page.pdf({ format: 'A4', printBackground: true });
await browser.close();Then repeat the select and extract test above to confirm real text came through.
Caveats
Because page.pdf() uses print CSS, the layout can differ from what you see on screen. Add @media print rules for page breaks, hidden navigation, and widths. Puppeteer also leaves backgrounds out by default, which is why printBackground: true is set above.
If you must stay client-side, raising the scale in html2canvas options (the README example uses scale: 2) makes the image sharper, but the output is still an image and the text still will not be selectable.
Back to All Questions