Converting HTML to PDF with Puppeteer: Style Configuration and Pagination
Learn how to efficiently convert HTML to PDF using Puppeteer, focusing on style configuration, pagination, and performance optimization.

Turning HTML into PDFs is crucial for creating standardized documents like reports, invoices, and client materials. Puppeteer, a browser automation tool, helps you manage styles, layouts, and page breaks for professional PDF output. Here's a quick overview of what you can do with Puppeteer:
- Generate PDFs: Use Puppeteer to convert HTML into polished PDFs while running JavaScript and applying custom CSS.
- Control Styles: Define page sizes, margins, fonts, headers, footers, and more using print-specific CSS.
- Manage Page Breaks: Use CSS rules to avoid splitting tables, headings, or images across pages.
- Optimize Performance: Improve quality and reduce file size with scaling, image optimization, and efficient resource handling.
Quick Start: Install Puppeteer with npm install puppeteer, load your HTML (as a string, local file, or URL), and configure PDF settings like dimensions, margins, and background rendering. Use @media print CSS rules for better control over print styles.
Key Features:
- Page customization with
@pagerules. - Header/footer templates for professional layouts.
- Multi-page content management to avoid awkward splits in tables or text.
With Puppeteer, you can automate and customize PDF generation for consistent, high-quality results.
🌐 Convert HTML to PDF with Puppeteer in Node.js 🚀 Full Step ...
Getting Started with Puppeteer
Learn how to set up and use Puppeteer to generate PDFs. Follow these steps to get started.
Setup
Before you begin, make sure you have Node.js version 14.0.0 or higher installed on your system. Here's how to set everything up:
- Install Node.js: Download it from nodejs.org and complete the installation.
- Create a project folder: Make a new folder for your project.
- Initialize the project: Open a terminal in your project folder and run
npm init -y. - Install Puppeteer: Use the command
npm install puppeteerto add Puppeteer to your project.
First PDF Generation Script
Here’s a basic script to convert HTML into a PDF using Puppeteer:
<span class="hljs-keyword">const</span> puppeteer = <span class="hljs-built_in">require</span>(<span class="hljs-string">'puppeteer'</span>);
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">generatePDF</span>(<span class="hljs-params"></span>) {
<span class="hljs-keyword">const</span> browser = <span class="hljs-keyword">await</span> puppeteer.<span class="hljs-title function_">launch</span>();
<span class="hljs-keyword">const</span> page = <span class="hljs-keyword">await</span> browser.<span class="hljs-title function_">newPage</span>();
<span class="hljs-comment">// Set page content</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">setContent</span>(<span class="hljs-string">`
<html>
<body>
<h1>Sample PDF Document</h1>
<p>Generated with Puppeteer</p>
</body>
</html>
`</span>);
<span class="hljs-comment">// Generate PDF</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">pdf</span>({
<span class="hljs-attr">path</span>: <span class="hljs-string">'output.pdf'</span>,
<span class="hljs-attr">format</span>: <span class="hljs-string">'Letter'</span>,
<span class="hljs-attr">margin</span>: {
<span class="hljs-attr">top</span>: <span class="hljs-string">'1in'</span>,
<span class="hljs-attr">right</span>: <span class="hljs-string">'1in'</span>,
<span class="hljs-attr">bottom</span>: <span class="hljs-string">'1in'</span>,
<span class="hljs-attr">left</span>: <span class="hljs-string">'1in'</span>
}
});
<span class="hljs-keyword">await</span> browser.<span class="hljs-title function_">close</span>();
}
<span class="hljs-title function_">generatePDF</span>();
Save this script as generate-pdf.js. Run it by typing node generate-pdf.js in your terminal. The script will create a PDF with US Letter dimensions (8.5×11 inches) and 1-inch margins.
HTML Source Options
Puppeteer provides multiple ways to load HTML content for PDF generation:
Direct Content Loading: Use a string containing the HTML.
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">setContent</span>(htmlString);Local File Access: Load an HTML file from your local system.
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">goto</span>(<span class="hljs-string">`file:<span class="hljs-subst">${path.join(__dirname, <span class="hljs-string">'template.html'</span>)}</span>`</span>);Remote URL Loading: Fetch HTML from a live website.
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">goto</span>(<span class="hljs-string">'https://yourwebsite.com/page-to-convert'</span>);
When working with external resources like images or styles, make sure they are embedded, use absolute URLs, or are stored locally.
Tips for Better Performance
To ensure smooth PDF generation, keep these pointers in mind:
- Use
page.waitForNetworkIdle()to wait for all network requests to finish. - Set appropriate timeouts for loading resources.
- Handle font loading explicitly to avoid rendering problems.
Once your HTML is ready, you can move on to customizing the PDF’s styles and settings.
PDF Style Settings
Print-Specific CSS Rules
To tailor your content for PDF output, use @media print rules. Here's an example:
<span class="hljs-keyword">@media</span> print {
<span class="hljs-comment">/* Hide navigation menus and non-essential elements */</span>
<span class="hljs-selector-tag">nav</span>, <span class="hljs-selector-tag">button</span>, <span class="hljs-selector-class">.no-print</span> {
<span class="hljs-attribute">display</span>: none;
}
<span class="hljs-comment">/* Adjust text for better readability in PDFs */</span>
<span class="hljs-selector-tag">body</span> {
<span class="hljs-attribute">font-size</span>: <span class="hljs-number">12pt</span>;
<span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.5</span>;
}
<span class="hljs-comment">/* Ensure accurate background rendering */</span>
* {
-webkit-<span class="hljs-attribute">print-color-adjust</span>: exact;
}
}
If you want to keep your screen-based styles instead of applying print-specific styles, include this line before generating the PDF:
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">emulateMediaType</span>(<span class="hljs-string">'screen'</span>);
Once print styles are applied, you can move on to layout adjustments.
Page Layout Settings
Define PDF dimensions using Puppeteer options or CSS @page rules. For Puppeteer, you can use the following configuration:
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">pdf</span>({
<span class="hljs-attr">format</span>: <span class="hljs-string">'Letter'</span>,
<span class="hljs-attr">margin</span>: {
<span class="hljs-attr">top</span>: <span class="hljs-string">'0.75in'</span>,
<span class="hljs-attr">right</span>: <span class="hljs-string">'0.5in'</span>,
<span class="hljs-attr">bottom</span>: <span class="hljs-string">'0.75in'</span>,
<span class="hljs-attr">left</span>: <span class="hljs-string">'0.5in'</span>
},
<span class="hljs-attr">landscape</span>: <span class="hljs-literal">false</span>,
<span class="hljs-attr">preferCSSPageSize</span>: <span class="hljs-literal">true</span>
});
For more customized page sizes, rely on CSS @page rules:
<span class="hljs-keyword">@page</span> {
size: <span class="hljs-number">8.5in</span> <span class="hljs-number">11in</span>;
<span class="hljs-attribute">margin</span>: <span class="hljs-number">0.75in</span> <span class="hljs-number">0.5in</span>;
}
After setting up the layout, you can fine-tune the design elements for a polished look.
Text and Design Elements
To make the content visually clear and professional, use these CSS rules:
<span class="hljs-selector-tag">body</span> {
<span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Arial'</span>, sans-serif;
<span class="hljs-attribute">color</span>: <span class="hljs-number">#333333</span>;
}
<span class="hljs-selector-tag">h1</span>, <span class="hljs-selector-tag">h2</span>, <span class="hljs-selector-tag">h3</span> {
<span class="hljs-attribute">page-break-after</span>: avoid;
<span class="hljs-attribute">color</span>: <span class="hljs-number">#000000</span>;
}
<span class="hljs-selector-tag">table</span> {
<span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
<span class="hljs-attribute">border-collapse</span>: collapse;
<span class="hljs-attribute">page-break-inside</span>: avoid;
}
<span class="hljs-selector-tag">img</span> {
<span class="hljs-attribute">max-width</span>: <span class="hljs-number">100%</span>;
<span class="hljs-attribute">height</span>: auto;
<span class="hljs-attribute">page-break-inside</span>: avoid;
}
For consistent background colors, especially in critical sections, add this rule:
<span class="hljs-selector-class">.color-critical</span> {
-webkit-<span class="hljs-attribute">print-color-adjust</span>: exact;
}
These adjustments ensure your PDF is easy to read and visually appealing.
sbb-itb-23997f1
Page Break Control
Page Break CSS Properties
Managing page breaks effectively ensures your content flows smoothly across pages. Use these CSS properties to control where content divides:
<span class="hljs-comment">/* Start new page before chapters */</span>
<span class="hljs-selector-class">.chapter</span> {
<span class="hljs-attribute">page-break-before</span>: always;
}
<span class="hljs-comment">/* Keep headings together with their content */</span>
<span class="hljs-selector-tag">h2</span>, <span class="hljs-selector-tag">h3</span> {
<span class="hljs-attribute">page-break-after</span>: avoid;
}
<span class="hljs-comment">/* Avoid splitting tables or figures */</span>
<span class="hljs-selector-tag">table</span>, <span class="hljs-selector-tag">figure</span> {
<span class="hljs-attribute">page-break-inside</span>: avoid;
}
These rules help keep your document organized and easy to read. Once you’ve set up page breaks, focus on configuring headers and footers to align with these settings.
Header and Footer Setup
Set up headers and footers in Puppeteer to give your PDF a professional look:
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">pdf</span>({
<span class="hljs-attr">displayHeaderFooter</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">headerTemplate</span>: <span class="hljs-string">`
<div style="font-size: 10px; padding: 0 0.5in; width: 100%;">
<span class="title"></span>
<span class="date" style="float: right;"></span>
</div>
`</span>,
<span class="hljs-attr">footerTemplate</span>: <span class="hljs-string">`
<div style="font-size: 10px; text-align: center; width: 100%;">
Page <span class="pageNumber"></span> of <span class="totalPages"></span>
</div>
`</span>,
<span class="hljs-attr">margin</span>: {
<span class="hljs-attr">top</span>: <span class="hljs-string">'1in'</span>,
<span class="hljs-attr">bottom</span>: <span class="hljs-string">'1in'</span>
}
});
Make sure to adjust the margins so the header and footer fit properly without overlapping your content.
Multi-Page Content Management
With page breaks and headers/footers in place, focus on managing content across multiple pages. Proper layout control ensures your document remains clear and professional:
<span class="hljs-comment">/* Keep captions with their images */</span>
<span class="hljs-selector-tag">figure</span> {
<span class="hljs-attribute">display</span>: table;
<span class="hljs-attribute">page-break-inside</span>: avoid;
}
<span class="hljs-selector-tag">figcaption</span> {
<span class="hljs-attribute">display</span>: table-caption;
<span class="hljs-attribute">caption-side</span>: bottom;
}
<span class="hljs-comment">/* Avoid splitting list items or table rows */</span>
<span class="hljs-selector-tag">li</span>, <span class="hljs-selector-class">.table-row</span> {
<span class="hljs-attribute">page-break-inside</span>: avoid;
}
<span class="hljs-comment">/* Allow large tables to break across pages */</span>
<span class="hljs-selector-class">.table-wrapper</span> {
<span class="hljs-attribute">page-break-inside</span>: auto;
}
For large tables that span multiple pages, wrap them in a container allowing breaks while keeping rows intact. This ensures data remains easy to follow, even in lengthy datasets.
Tip: Enable the
printBackgroundoption in Puppeteer to render all visual elements, including background colors and images:
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">pdf</span>({
<span class="hljs-attr">printBackground</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">preferCSSPageSize</span>: <span class="hljs-literal">true</span>
});
PDF Quality and Performance
Improving PDF quality and performance requires attention to scaling, image handling, and resource management. These steps ensure the final document looks polished and functions efficiently.
Content Scaling Methods
Scaling content correctly ensures it remains readable and consistent in design. Puppeteer offers detailed scaling controls for rendering PDFs:
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">pdf</span>({
<span class="hljs-attr">scale</span>: <span class="hljs-number">0.8</span>,
<span class="hljs-attr">preferCSSPageSize</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">format</span>: <span class="hljs-string">'Letter'</span>
});
Here, values below 1 shrink content, while values above 1 enlarge it. Pairing scaling with preferCSSPageSize ensures the PDF adheres to CSS-defined dimensions:
<span class="hljs-keyword">@page</span> {
size: <span class="hljs-number">8.5in</span> <span class="hljs-number">11in</span>;
<span class="hljs-attribute">margin</span>: <span class="hljs-number">0.5in</span>;
}
Image Quality Management
Choosing the right image format is crucial. PNG works well for detailed visuals like charts and logos but can increase file size. JPEG is a better option for photos, while WebP often gets converted, potentially inflating the file size further.
To improve image clarity, increase the device scale factor:
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">setViewport</span>({
<span class="hljs-attr">width</span>: <span class="hljs-number">1200</span>,
<span class="hljs-attr">height</span>: <span class="hljs-number">800</span>,
<span class="hljs-attr">deviceScaleFactor</span>: <span class="hljs-number">2</span>
});
Common Issues and Solutions
Addressing common challenges like resource management, file size, and errors can significantly boost performance.
Resource Management
Use a single browser instance and page to handle multiple PDF requests, reducing overhead:<span class="hljs-keyword">const</span> browser = <span class="hljs-keyword">await</span> puppeteer.<span class="hljs-title function_">launch</span>({ <span class="hljs-attr">args</span>: [<span class="hljs-string">'--no-sandbox'</span>, <span class="hljs-string">'--disable-setuid-sandbox'</span>] }); <span class="hljs-keyword">const</span> page = <span class="hljs-keyword">await</span> browser.<span class="hljs-title function_">newPage</span>(); <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> request <span class="hljs-keyword">of</span> requests) { <span class="hljs-keyword">await</span> <span class="hljs-title function_">generatePDF</span>(page, request); }File Size Optimization
Minimize file size by removing unnecessary elements and optimizing images:<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">evaluate</span>(<span class="hljs-function">() =></span> { <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelectorAll</span>(<span class="hljs-string">'.no-print'</span>).<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">el</span> =></span> el.<span class="hljs-title function_">remove</span>()); <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelectorAll</span>(<span class="hljs-string">'img'</span>).<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">img</span> =></span> { img.<span class="hljs-property">loading</span> = <span class="hljs-string">'lazy'</span>; img.<span class="hljs-property">decoding</span> = <span class="hljs-string">'async'</span>; }); });Error Handling
Implement strategies to handle errors like timeouts and retries:<span class="hljs-keyword">const</span> <span class="hljs-title function_">generatePDF</span> = <span class="hljs-keyword">async</span> (<span class="hljs-params">page, options</span>) => { <span class="hljs-keyword">try</span> { <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">goto</span>(options.<span class="hljs-property">url</span>, { <span class="hljs-attr">waitUntil</span>: <span class="hljs-string">'networkidle0'</span>, <span class="hljs-attr">timeout</span>: <span class="hljs-number">30000</span> }); <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">pdf</span>(options); } <span class="hljs-keyword">catch</span> (error) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">'PDF generation failed:'</span>, error); <span class="hljs-keyword">throw</span> error; } };
Conclusion
Using Puppeteer to convert HTML to PDF provides effective tools for creating professional-grade documents.
Key Steps to Follow
- Apply print media settings with
page.emulateMediaType('print'). - Use CSS rules like
page-break-inside: avoidto ensure elements such as table rows stay intact.
These techniques build on earlier styling and layout methods, serving as a solid base for more advanced automation.
Advanced Automation Options
You can take PDF generation further with these additional automation features:
- Environment Configuration
Set up cache directories and browser settings to ensure consistent results across different platforms. - Performance Tweaks
Adjust timeout settings and add retry mechanisms to improve reliability during the generation process.
When deploying these methods in production, include error handling and logging to maintain consistent and reliable PDF outputs.
Related posts
- Installing and Configuring Puppeteer: Solving Common Dependency and Chromium Issues
- Complete Guide to PDF Generation with Puppeteer: From Simple Documents to Complex Reports
- Browser Automation with Puppeteer and JavaScript: Practical Implementation in Node.js
- Cache Management in Puppeteer: Disabling, Clearing, and Performance Optimization



