npx skills add ...
npx skills add aviz85/claude-skills-library --skill html-to-pdf
Convert HTML to PDF with pixel-perfect rendering and excellent Hebrew/RTL support. Use when the user asks to 'convert HTML to PDF', 'generate PDF from HTML', 'create PDF from webpage', 'export to PDF', or needs PDF generation with Hebrew text support.
npx skills add aviz85/claude-skills-library --skill html-to-pdf
Pixel-perfect HTML to PDF conversion using Puppeteer (Chrome headless). Provides excellent support for Hebrew, Arabic, and other RTL languages with automatic direction detection.
The script automatically handles content overflow:
This runs automatically on every PDF generation. No flags needed.
Backgrounds on html or body cause extra pages! Put backgrounds on a container element instead:
Common causes of extra pages:
.container insteadoverflow: hiddenTips:
--scale=0.75 --margin=0 if content still overflows--landscapeBefore first use, install dependencies:
| Option | Description | Default |
|---|---|---|
--format=<format> | Page format: A4, Letter, Legal, A3, A5 | A4 |
--landscape | Use landscape orientation | false |
--margin=<value> | Set all margins (e.g., "20mm", "1in") | 20mm |
--margin-top=<value> | Top margin | 20mm |
--margin-right=<value> | Right margin | 20mm |
--margin-bottom=<value> | Bottom margin | 20mm |
--margin-left=<value> | Left margin | 20mm |
--scale=<number> | Scale factor 0.1-2.0 | 1 |
--background | Print background graphics | true |
--no-background | Don't print backgrounds | - |
--header=<html> | Header HTML template | - |
--footer=<html> | Footer HTML template | - |
--wait=<ms> | Wait time for fonts/JS | 1000 |
--rtl | Force RTL direction | auto-detect |
--expect-pages=<N> | Expected page count (warns if different) | 1 |
--no-page-check | Disable page count warning | - |
The script automatically checks page count after generating the PDF. By default, it expects 1 page and warns if the output has more:
Usage:
--expect-pages=3: expects 3 pages (for multi-page documents)--no-page-check: disables the check entirelyNote: Requires pdfinfo to be installed (part of poppler-utils). If not available, the check is silently skipped.
For best Hebrew rendering in your HTML:
<html lang="he" dir="rtl"><meta charset="UTF-8">direction: rtl; text-align: right; to bodyNEVER use --scale < 1.0 for multi-page documents. It causes:
Instead: reduce CSS font sizes and spacing to fit content at scale=1.0.
If content overflows at scale=1.0: reduce font sizes (10-11px base), padding, margins — NOT the scale. This keeps 1:1 mapping between CSS and PDF, eliminating all layout artifacts.
Color tip: Pure white (#fff) backgrounds wash out colored accents. Use #f7f8fa or #f8fafb for subtle contrast that makes colors pop.
--wait=2000 for more font loading time@font-face or Google Fonts--rtl flag to force RTL directiondir="rtl" to your HTML elementUse CSS page-break properties:
--background is set (default is true)--no-background only if you want to exclude backgroundsCRITICAL - Claude MUST do this after EVERY PDF generation:
This is NOT optional. Never deliver a PDF without visual verification.
| Problem | Symptom | Fix |
|---|---|---|
| Vertical overflow | Empty space at page bottom, content on next page | Reduce --scale |
| Horizontal cut-off | Text cut at left/right edges | Reduce --margin AND fix HTML width |
| Both issues | Content cut AND extra pages | Fix HTML CSS first, then adjust scale |
Attempt 1: Default settings
Attempt 2: If vertical overflow → reduce scale
Attempt 3: If horizontal cut-off → reduce margins
Attempt 4: If still issues → smaller scale + margins
Attempt 5: If still failing → FIX THE HTML CSS:
STOP after 5 attempts - regenerate HTML with proper constraints.
If content is cut at sides, the HTML MUST have:
After EVERY PDF generation, verify:
If ANY check fails → adjust and regenerate (max 5 times).
networkidle0 to ensure all resources loaddocument.fonts.ready@page CSS rules for print stylingcd ~/.claude/skills/html-to-pdf && npm installnode ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js input.html output.pdfnode ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js https://example.com page.pdfnode ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js hebrew.html hebrew.pdf --rtlecho "<h1>שלום עולם</h1>" | node ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js - output.pdf --rtl⚠️ WARNING: PAGE OVERFLOW DETECTED!
Expected: 1 page(s)
Actual: 2 page(s)
Fix: Reduce content, margins, or font sizes in HTML
Use --no-page-check to disable this warningnode ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js report.html report.pdfnode ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js doc.html doc.pdf --format=Letter --margin=1innode ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js invoice-he.html invoice.pdf --rtlnode ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js slides.html slides.pdf --landscape --format=A4node ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js poster.html poster.pdf --margin=0<!DOCTYPE html>
<html lang="he" dir="rtl">
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Heebo:wght@400;700&display=swap" rel="stylesheet">
<style>
@page { size: A4; margin: 0; }
html, body {
width: 210mm;
height: 297mm;
margin: 0;
padding: 0;
overflow: hidden;
}
.container {
width: 100%;
height: 100%;
padding: 20mm;
box-sizing: border-box;
font-family: 'Heebo', sans-serif;
direction: rtl;
text-align: right;
background: #f5f5f5; /* Background on container, NOT body */
}
</style>
</head>
<body>
<div class="container">
<h1>שלום עולם</h1>
<p>זהו מסמך בעברית</p>
</div>
</body>
</html>.page {
width: 210mm; /* Matches A4 exactly at scale=1.0 */
height: 297mm; /* Matches A4 exactly at scale=1.0 */
padding: 8mm 10mm 12mm;
page-break-after: always;
position: relative;
background: #f7f8fa;
overflow: hidden;
box-sizing: border-box;
}.page-break { page-break-after: always; }
.no-break { page-break-inside: avoid; }node scripts/html-to-pdf.js input.html output.pdfnode scripts/html-to-pdf.js input.html output.pdf --scale=0.9node scripts/html-to-pdf.js input.html output.pdf --scale=0.9 --margin=10mmnode scripts/html-to-pdf.js input.html output.pdf --scale=0.8 --margin=5mm/* Add to HTML to prevent horizontal overflow */
.container {
width: 100%;
max-width: 100%;
overflow-wrap: break-word;
word-wrap: break-word;
box-sizing: border-box;
}html, body {
width: 210mm; /* A4 width */
margin: 0;
padding: 0;
overflow: hidden;
}
.container {
width: 100%;
max-width: 100%;
padding: 15mm;
box-sizing: border-box;
overflow-wrap: break-word;
}