
Html To Pdf
- 1.1k installs
- 44 repo stars
- Updated July 8, 2026
- aviz85/claude-skills-library
html-to-pdf provides documented workflows for 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', 'c
About
The html-to-pdf skill 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. # HTML to PDF Converter Pixel-perfect HTML to PDF conversion using Puppeteer (Chrome headless). Provides excellent support for Hebrew, Arabic, and other RTL languages with automatic direction detection. - **Pixel-perfect rendering**: Uses actual Chrome engine - **Full CSS3/HTML5 support**: Flexbox, Grid, custom fonts, backgrounds - **JavaScript execution**: Renders dynamic content - **Automatic RTL detection**: Detects Hebrew/Arabic and sets direction - **Web font support**: Loads custom fonts properly ## Auto-Fit (Built-in, No Flag Needed) The script automatically handles content overflow: - **Small overflow (up to ~18%)** → auto-shrinks font size to fit the page - **Large content** → flows cleanly across multiple pages with smart page-break rules (no cutting headers, table rows, or images in half) - **Fits perfectly** → does nothing This runs automatically on every PDF generation.
- **Pixel-perfect rendering**: Uses actual Chrome engine
- **Full CSS3/HTML5 support**: Flexbox, Grid, custom fonts, backgrounds
- **JavaScript execution**: Renders dynamic content
- **Automatic RTL detection**: Detects Hebrew/Arabic and sets direction
- **Web font support**: Loads custom fonts properly
Html To Pdf by the numbers
- 1,131 all-time installs (skills.sh)
- +18 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #216 of 1,039 Mobile Development skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 2, 2026 (Skillselion catalog sync)
html-to-pdf capabilities & compatibility
- Capabilities
- **pixel perfect rendering**: uses actual chrome · **full css3/html5 support**: flexbox, grid, cust · **javascript execution**: renders dynamic conten · **automatic rtl detection**: detects hebrew/arab · **web font support**: loads custom fonts properl
- Use cases
- documentation
What html-to-pdf says it does
# HTML to PDF Converter Pixel-perfect HTML to PDF conversion using Puppeteer (Chrome headless).
Provides excellent support for Hebrew, Arabic, and other RTL languages with automatic direction detection.
npx skills add https://github.com/aviz85/claude-skills-library --skill html-to-pdfAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.1k |
|---|---|
| repo stars | ★ 44 |
| Security audit | 2 / 3 scanners passed |
| Last updated | July 8, 2026 |
| Repository | aviz85/claude-skills-library ↗ |
How do I use html-to-pdf for the task described in its SKILL.md triggers?
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.
Who is it for?
Teams invoking html-to-pdf when the user request matches documented triggers and prerequisites.
Skip if: Skip when cached docs are missing, the request is a negative trigger, or another sibling skill owns the workflow.
When should I use this skill?
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 gener
What you get
Step-by-step guidance grounded in html-to-pdf documentation and reference files.
- Generated PDF file from HTML input
By the numbers
- Package version 1.0.0
- Depends on puppeteer ^22.0.0
Files
HTML to PDF Converter
Pixel-perfect HTML to PDF conversion using Puppeteer (Chrome headless). Provides excellent support for Hebrew, Arabic, and other RTL languages with automatic direction detection.
Why Puppeteer?
- Pixel-perfect rendering: Uses actual Chrome engine
- Full CSS3/HTML5 support: Flexbox, Grid, custom fonts, backgrounds
- JavaScript execution: Renders dynamic content
- Automatic RTL detection: Detects Hebrew/Arabic and sets direction
- Web font support: Loads custom fonts properly
Auto-Fit (Built-in, No Flag Needed)
The script automatically handles content overflow:
- Small overflow (up to ~18%) → auto-shrinks font size to fit the page
- Large content → flows cleanly across multiple pages with smart page-break rules (no cutting headers, table rows, or images in half)
- Fits perfectly → does nothing
This runs automatically on every PDF generation. No flags needed.
CRITICAL: Fit Content to Single Page
Backgrounds on `html` or `body` cause extra pages! Put backgrounds on a container element instead:
@page { size: A4; margin: 0; }
html, body {
width: 210mm;
height: 297mm;
margin: 0;
padding: 0;
overflow: hidden;
/* NO background here! */
}
.container {
width: 100%;
height: 100%;
padding: 20mm;
box-sizing: border-box;
background: linear-gradient(...); /* Background goes HERE */
}Common causes of extra pages: 1. Background on html/body - always put on .container instead 2. Content overflow - use overflow: hidden 3. Margins/padding pushing content out
Tips:
- Use
--scale=0.75 --margin=0if content still overflows - For landscape: use
--landscape
Setup (One-time)
Before first use, install dependencies:
cd ~/.claude/skills/html-to-pdf && npm installQuick Usage
Convert local HTML file:
node ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js input.html output.pdfConvert URL to PDF:
node ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js https://example.com page.pdfHebrew document with forced RTL:
node ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js hebrew.html hebrew.pdf --rtlPipe HTML content:
echo "<h1>שלום עולם</h1>" | node ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js - output.pdf --rtlOptions Reference
| 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 | - |
Automatic Overflow Detection
The script automatically checks page count after generating the PDF. By default, it expects 1 page and warns if the output has more:
⚠️ 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 warningUsage:
- Default: expects 1 page, warns on overflow
--expect-pages=3: expects 3 pages (for multi-page documents)--no-page-check: disables the check entirely
Note: Requires pdfinfo to be installed (part of poppler-utils). If not available, the check is silently skipped.
Examples
Basic conversion:
node ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js report.html report.pdfLetter format with custom margins:
node ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js doc.html doc.pdf --format=Letter --margin=1inHebrew invoice:
node ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js invoice-he.html invoice.pdf --rtlLandscape presentation:
node ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js slides.html slides.pdf --landscape --format=A4No margins (full bleed):
node ~/.claude/skills/html-to-pdf/scripts/html-to-pdf.js poster.html poster.pdf --margin=0Hebrew/RTL Best Practices
For best Hebrew rendering in your HTML:
1. Set lang attribute: <html lang="he" dir="rtl"> 2. Use UTF-8: <meta charset="UTF-8"> 3. CSS direction: Add direction: rtl; text-align: right; to body 4. Fonts: Use web fonts that support Hebrew (Noto Sans Hebrew, Heebo, Assistant)
Example Hebrew HTML structure (single-page):
<!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>CRITICAL: Always Use scale=1.0 for Multi-Page PDFs
NEVER use `--scale` < 1.0 for multi-page documents. It causes:
- Content offset (not centered on page)
- RTL text overflow/clipping in grid layouts
- Unpredictable viewport width calculations
Instead: reduce CSS font sizes and spacing to fit content at scale=1.0.
.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;
}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.
Troubleshooting
Fonts not rendering correctly
- Add
--wait=2000for more font loading time - Ensure fonts are loaded via
@font-faceor Google Fonts
Hebrew appearing left-to-right
- Use
--rtlflag to force RTL direction - Add
dir="rtl"to your HTML element
Page breaks not working
Use CSS page-break properties:
.page-break { page-break-after: always; }
.no-break { page-break-inside: avoid; }Backgrounds not showing
- Ensure
--backgroundis set (default is true) - Use
--no-backgroundonly if you want to exclude backgrounds
Auto-Fit Content (MANDATORY VERIFICATION)
CRITICAL - Claude MUST do this after EVERY PDF generation:
1. Read the PDF file using the Read tool to visually inspect it 2. Check for vertical overflow (empty pages, content spilling to next page) 3. Check for horizontal overflow (text cut off at sides) 4. If ANY issue found → FIX and regenerate (max 5 attempts) 5. Only deliver PDF to user after verification passes
This is NOT optional. Never deliver a PDF without visual verification.
Problems to Look For
| 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 |
Fix Strategy (Max 5 Attempts)
Attempt 1: Default settings
node scripts/html-to-pdf.js input.html output.pdfAttempt 2: If vertical overflow → reduce scale
node scripts/html-to-pdf.js input.html output.pdf --scale=0.9Attempt 3: If horizontal cut-off → reduce margins
node scripts/html-to-pdf.js input.html output.pdf --scale=0.9 --margin=10mmAttempt 4: If still issues → smaller scale + margins
node scripts/html-to-pdf.js input.html output.pdf --scale=0.8 --margin=5mmAttempt 5: If still failing → FIX THE HTML CSS:
/* 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;
}STOP after 5 attempts - regenerate HTML with proper constraints.
HTML Width Fix (Required for Horizontal Fit)
If content is cut at sides, the HTML MUST have:
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;
}Verification Checklist
After EVERY PDF generation, verify:
- [ ] All text visible (not cut at edges)
- [ ] No unnecessary empty pages
- [ ] Content fills pages properly
- [ ] No large gaps between sections
If ANY check fails → adjust and regenerate (max 5 times).
Technical Notes
- Uses Puppeteer with Chrome headless for rendering
- Waits for
networkidle0to ensure all resources load - Automatically waits for
document.fonts.ready - Supports
@pageCSS rules for print styling - Device scale factor set to 2 for crisp rendering
{
"name": "html-to-pdf-skill",
"version": "1.0.0",
"description": "Pixel-perfect HTML to PDF converter with Hebrew/RTL support using Puppeteer",
"main": "scripts/html-to-pdf.js",
"bin": {
"html-to-pdf": "./scripts/html-to-pdf.js"
},
"scripts": {
"convert": "node scripts/html-to-pdf.js"
},
"dependencies": {
"puppeteer": "^22.0.0"
},
"keywords": [
"html",
"pdf",
"puppeteer",
"hebrew",
"rtl",
"converter"
],
"license": "MIT"
}
#!/usr/bin/env node
/**
* HTML to PDF Converter with Hebrew/RTL Support
* Uses Puppeteer for pixel-perfect rendering
*
* Usage:
* node html-to-pdf.js <input> <output> [options]
*
* Input can be:
* - Local HTML file path
* - URL (http:// or https://)
* - "-" for stdin (pipe HTML content)
*
* Options:
* --format=<format> Page format: A4, Letter, Legal, A3, A5 (default: A4)
* --landscape Use landscape orientation
* --margin=<value> Set all margins (e.g., "20mm" or "1in")
* --margin-top=<value> Top margin
* --margin-right=<value> Right margin
* --margin-bottom=<value> Bottom margin
* --margin-left=<value> Left margin
* --scale=<number> Scale factor 0.1-2.0 (default: 1)
* --background Print background graphics (default: true)
* --no-background Don't print background graphics
* --header=<html> Header HTML template
* --footer=<html> Footer HTML template
* --wait=<ms> Additional wait time for fonts/JS (default: 1000)
* --rtl Force RTL direction
* --font=<path> Load additional font file
*/
const puppeteer = require('puppeteer');
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
// Parse command line arguments
function parseArgs(args) {
const options = {
input: null,
output: null,
format: 'A4',
landscape: false,
margin: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' },
scale: 1,
printBackground: true,
headerTemplate: '',
footerTemplate: '',
displayHeaderFooter: false,
waitTime: 1000,
forceRtl: false,
additionalFonts: [],
expectPages: 1 // Expected page count (0 = no check)
};
const positional = [];
for (const arg of args) {
if (arg.startsWith('--')) {
const [key, value] = arg.slice(2).split('=');
switch (key) {
case 'format':
options.format = value;
break;
case 'landscape':
options.landscape = true;
break;
case 'margin':
options.margin = { top: value, right: value, bottom: value, left: value };
break;
case 'margin-top':
options.margin.top = value;
break;
case 'margin-right':
options.margin.right = value;
break;
case 'margin-bottom':
options.margin.bottom = value;
break;
case 'margin-left':
options.margin.left = value;
break;
case 'scale':
options.scale = parseFloat(value);
break;
case 'background':
options.printBackground = true;
break;
case 'no-background':
options.printBackground = false;
break;
case 'header':
options.headerTemplate = value;
options.displayHeaderFooter = true;
break;
case 'footer':
options.footerTemplate = value;
options.displayHeaderFooter = true;
break;
case 'wait':
options.waitTime = parseInt(value, 10);
break;
case 'rtl':
options.forceRtl = true;
break;
case 'font':
options.additionalFonts.push(value);
break;
case 'expect-pages':
options.expectPages = parseInt(value, 10);
break;
case 'no-page-check':
options.expectPages = 0;
break;
}
} else {
positional.push(arg);
}
}
options.input = positional[0];
options.output = positional[1];
return options;
}
// Check PDF page count using pdfinfo
function checkPdfPageCount(pdfPath, expectedPages) {
if (expectedPages <= 0) return { ok: true, pages: 0 };
try {
const output = execSync(`pdfinfo "${pdfPath}" 2>&1`, { encoding: 'utf8' });
const match = output.match(/Pages:\s*(\d+)/);
const pages = match ? parseInt(match[1], 10) : 0;
if (pages === 0) {
// Could not parse, skip check
return { ok: true, pages: 0, skipped: true };
}
return {
ok: pages === expectedPages,
pages,
expected: expectedPages
};
} catch (e) {
// pdfinfo not available, skip check
return { ok: true, pages: 0, skipped: true };
}
}
// Detect if content contains RTL characters (Hebrew, Arabic)
function containsRtlCharacters(text) {
// Hebrew: \u0590-\u05FF, Arabic: \u0600-\u06FF, \u0750-\u077F
const rtlPattern = /[\u0590-\u05FF\u0600-\u06FF\u0750-\u077F]/;
return rtlPattern.test(text);
}
// Read input from file, URL, or stdin
async function getInputContent(input) {
if (input === '-') {
// Read from stdin
return new Promise((resolve, reject) => {
let data = '';
process.stdin.setEncoding('utf8');
process.stdin.on('data', chunk => data += chunk);
process.stdin.on('end', () => resolve({ type: 'html', content: data }));
process.stdin.on('error', reject);
});
} else if (input.startsWith('http://') || input.startsWith('https://')) {
return { type: 'url', content: input };
} else {
const absolutePath = path.resolve(input);
if (!fs.existsSync(absolutePath)) {
throw new Error(`File not found: ${absolutePath}`);
}
return { type: 'file', content: absolutePath };
}
}
// CSS to inject for proper RTL and font support
function getRtlCss(forceRtl) {
return `
/* Hebrew/RTL Support CSS */
@font-face {
font-family: 'Noto Sans Hebrew';
src: local('Noto Sans Hebrew'), local('NotoSansHebrew');
unicode-range: U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
/* Ensure proper RTL handling */
[lang="he"], [lang="iw"], [dir="rtl"], .rtl {
direction: rtl;
text-align: right;
}
/* Auto-detect RTL content */
:lang(he), :lang(iw), :lang(ar) {
direction: rtl;
text-align: right;
}
${forceRtl ? `
html, body {
direction: rtl;
text-align: right;
}
` : ''}
/* Improve print quality */
@media print {
* {
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
}
`;
}
async function convertHtmlToPdf(options) {
const browser = await puppeteer.launch({
headless: 'new',
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--font-render-hinting=none',
'--disable-font-subpixel-positioning'
]
});
try {
const page = await browser.newPage();
// Set viewport for consistent rendering
await page.setViewport({ width: 1200, height: 800, deviceScaleFactor: 2 });
// Get input content
const input = await getInputContent(options.input);
// Navigate to content
if (input.type === 'url') {
await page.goto(input.content, {
waitUntil: ['networkidle0', 'domcontentloaded'],
timeout: 60000
});
} else if (input.type === 'file') {
await page.goto(`file://${input.content}`, {
waitUntil: ['networkidle0', 'domcontentloaded'],
timeout: 60000
});
} else {
await page.setContent(input.content, {
waitUntil: ['networkidle0', 'domcontentloaded'],
timeout: 60000
});
}
// Inject RTL/font support CSS
await page.addStyleTag({ content: getRtlCss(options.forceRtl) });
// Auto-detect RTL content and set direction if needed
const pageContent = await page.content();
const hasRtl = containsRtlCharacters(pageContent);
if (hasRtl || options.forceRtl) {
await page.evaluate(() => {
// Check if already has direction set
const html = document.documentElement;
const body = document.body;
if (!html.getAttribute('dir') && !body.getAttribute('dir')) {
// Auto-set RTL for Hebrew content
const text = body.innerText || '';
const hebrewPattern = /[\u0590-\u05FF]/;
if (hebrewPattern.test(text)) {
html.setAttribute('dir', 'rtl');
html.setAttribute('lang', 'he');
}
}
});
}
// Wait for fonts to load
await page.evaluateHandle('document.fonts.ready');
// Additional wait for complex content/fonts
if (options.waitTime > 0) {
await new Promise(resolve => setTimeout(resolve, options.waitTime));
}
// Add clean page-break rules for all documents
await page.evaluate(() => {
const style = document.createElement('style');
style.textContent = `
h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
tr, img, figure, blockquote, pre, .no-break { page-break-inside: avoid; }
table { page-break-inside: auto; }
p { orphans: 3; widows: 3; }
`;
document.head.appendChild(style);
});
// Generate PDF
const pdfOptions = {
path: options.output,
format: options.format,
landscape: options.landscape,
margin: options.margin,
scale: options.scale,
printBackground: options.printBackground,
displayHeaderFooter: options.displayHeaderFooter,
headerTemplate: options.headerTemplate,
footerTemplate: options.footerTemplate,
preferCSSPageSize: true
};
await page.pdf(pdfOptions);
console.log(`PDF generated successfully: ${options.output}`);
// Auto-fit: if PDF has 2 pages but expected 1, try CSS zoom to fit
const pageCheck = checkPdfPageCount(options.output, options.expectPages);
if (!pageCheck.skipped && pageCheck.pages === 2 && options.expectPages === 1) {
// Use CSS zoom (affects layout reflow in Chromium, RTL-safe)
const zoomLevels = [0.92, 0.88, 0.84, 0.80, 0.75];
for (const z of zoomLevels) {
await page.evaluate((zoom) => {
// Remove previous auto-fit
const prev = document.getElementById('autofit-zoom');
if (prev) prev.remove();
const style = document.createElement('style');
style.id = 'autofit-zoom';
style.textContent = `
html { zoom: ${zoom}; }
body { max-width: 100%; overflow: hidden; box-sizing: border-box; }
`;
document.head.appendChild(style);
}, z);
await page.pdf(pdfOptions);
const recheck = checkPdfPageCount(options.output, 1);
if (!recheck.skipped && recheck.pages === 1) {
console.log(`Auto-fit: shrunk to ${Math.round(z * 100)}% (CSS zoom) to fit 1 page`);
return { success: true, pages: 1, overflow: false };
}
}
// If still 2 pages, reset zoom and keep original
await page.evaluate(() => {
const prev = document.getElementById('autofit-zoom');
if (prev) prev.remove();
});
await page.pdf(pdfOptions);
console.log('Auto-fit: could not fit to 1 page (content too large), kept at 2 pages');
}
// Check page count for warnings
if (pageCheck.skipped) {
// pdfinfo not available, skip
} else if (!pageCheck.ok) {
console.log('');
if (pageCheck.pages > pageCheck.expected) {
console.log('⚠️ WARNING: PAGE OVERFLOW DETECTED!');
console.log(` Expected: ${pageCheck.expected} page(s)`);
console.log(` Actual: ${pageCheck.pages} page(s)`);
console.log('');
console.log(' Fix: Reduce content, margins, or font sizes in HTML');
} else {
console.log('⚠️ WARNING: Page count mismatch');
console.log(` Expected: ${pageCheck.expected} page(s)`);
console.log(` Actual: ${pageCheck.pages} page(s)`);
}
console.log(' Use --no-page-check to disable this warning');
console.log('');
}
return { success: true, pages: pageCheck.pages, overflow: !pageCheck.ok };
} finally {
await browser.close();
}
}
// Main execution
async function main() {
const args = process.argv.slice(2);
if (args.length < 2 || args.includes('--help') || args.includes('-h')) {
console.log(`
HTML to PDF Converter with Hebrew/RTL Support
==============================================
Usage:
html-to-pdf <input> <output.pdf> [options]
Input:
- Local HTML file path
- URL (http:// or https://)
- "-" for stdin (pipe HTML content)
Options:
--format=<format> Page format: A4, Letter, Legal, A3, A5 (default: A4)
--landscape Use landscape orientation
--margin=<value> Set all margins (e.g., "20mm" or "1in")
--margin-top=<value> Top margin
--margin-right=<value> Right margin
--margin-bottom=<value> Bottom margin
--margin-left=<value> Left margin
--scale=<number> Scale factor 0.1-2.0 (default: 1)
--background Print background graphics (default: true)
--no-background Don't print background graphics
--header=<html> Header HTML template
--footer=<html> Footer HTML template
--wait=<ms> Additional wait time for fonts/JS (default: 1000)
--rtl Force RTL direction for entire document
--expect-pages=<N> Expected page count, warns if different (default: 1)
--no-page-check Disable page count warning
Examples:
# Convert local HTML file
html-to-pdf document.html output.pdf
# Convert URL to PDF
html-to-pdf https://example.com page.pdf
# Hebrew document with forced RTL
html-to-pdf hebrew.html hebrew.pdf --rtl
# Custom margins and format
html-to-pdf doc.html out.pdf --format=Letter --margin=1in
# Pipe HTML content
echo "<h1>שלום עולם</h1>" | html-to-pdf - hello.pdf --rtl
`);
process.exit(args.includes('--help') || args.includes('-h') ? 0 : 1);
}
const options = parseArgs(args);
if (!options.input || !options.output) {
console.error('Error: Both input and output are required');
process.exit(1);
}
try {
await convertHtmlToPdf(options);
} catch (error) {
console.error(`Error: ${error.message}`);
process.exit(1);
}
}
main();
HTML to PDF - Setup Guide
Prerequisites
- Node.js installed
1. Install Dependencies
cd ~/.claude/skills/html-to-pdf
npm installThis installs Puppeteer which includes Chromium for rendering.
2. Test
# Create test HTML
echo "<h1>Test</h1>" > /tmp/test.html
# Convert to PDF
node scripts/html-to-pdf.js /tmp/test.html /tmp/test.pdf
# Check output
ls -la /tmp/test.pdfIf PDF is created, setup is complete!
3. Mark Setup Complete
Edit SKILL.md and change:
setup_complete: trueTroubleshooting
| Issue | Solution |
|---|---|
| Chromium download fails | Set PUPPETEER_SKIP_DOWNLOAD=true and install Chrome manually |
| Permission denied | Check write permissions on output path |
| Hebrew/RTL issues | The script handles RTL automatically |
| Missing fonts | Install system fonts for the language |
Related skills
How it compares
Use when browser-faithful HTML rendering and RTL matter; use lighter PDF libraries when templates are simple and Puppeteer overhead is unnecessary.
FAQ
What does html-to-pdf do?
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 gener
When should I use 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 gener
What are common prerequisites?
--- name: html-to-pdf description: Convert HTML to PDF with pixel-perfect rendering and excellent Hebrew/RTL support.
Is Html To Pdf safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.