IronPDF's most powerful and most popular feature is the ability to create high-fidelity PDFs from raw HTML, CSS, and JavaScript. This tutorial walks Node.js developers through every practical method for turning HTML content into PDFs — from a one-liner string conversion all the way to dynamic template-driven document generation.
IronPDF is a high-level API library that helps developers implement powerful PDF processing capabilities into software applications quickly. IronPDF is available in multiple programming languages. For detailed coverage on creating PDFs in .NET, Java, and Python, consult the official documentation pages. This tutorial covers its usage as it applies to Node.js projects.
Quickstart: Convert HTML to PDF in Node.js
How to Convert HTML to PDF in Node.js
- Install the IronPDF Node.js library via NPM:
npm install @ironsoftware/ironpdf - Import the PdfDocument class from the
@ironsoftware/ironpdfpackage. - Call
PdfDocument.fromHtml,PdfDocument.fromUrl, orPdfDocument.fromZipdepending on your HTML source. - Optionally configure rendering options: headers, footers, page size, orientation, and margins.
- Call
PdfDocument.saveAsto save the generated PDF to disk.
Table of Contents
- How Do You Get Started with IronPDF for Node.js?
- How Do You Convert HTML to PDF in Node.js?
- What Advanced Rendering Options Does IronPDF Support?
- How Do You Generate PDFs from an HTML Template?
- What Are the Next Steps?
How Do You Get Started with IronPDF for Node.js? {#getting-started}
Start using IronPDF in your project today with a free trial.
Install the IronPDF Library
Install the IronPDF Node.js package by running the NPM command below in your chosen Node.js project:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/install.sh
npm install @ironsoftware/ironpdf//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/install.sh
npm install @ironsoftware/ironpdfYou can also download and install the IronPDF package manually.
How Do You Install the IronPDF Engine?
IronPDF for Node.js requires an IronPDF Engine binary to function.
@ironsoftware/ironpdf package automatically downloads and installs the appropriate binary for your operating system on first execution. Explicit installation is recommended in environments where internet access is restricted or unavailable.Install the IronPDF Engine binary by installing the appropriate package for your operating system.
How Do You Apply a License Key?
By default, IronPDF brands all documents it generates or modifies with a watermark. To remove the watermark, set the licenseKey property on the global IronPdfGlobalConfig object with a valid license key:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/config.js
import { IronPdfGlobalConfig } from "@ironsoftware/ironpdf";
// Retrieve the global configuration object
var config = IronPdfGlobalConfig.getConfig();
// Set a valid license key to remove watermarks
config.licenseKey = "{YOUR-LICENSE-KEY-HERE}";//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/config.js
import { IronPdfGlobalConfig } from "@ironsoftware/ironpdf";
// Retrieve the global configuration object
var config = IronPdfGlobalConfig.getConfig();
// Set a valid license key to remove watermarks
config.licenseKey = "{YOUR-LICENSE-KEY-HERE}";Obtain a free trial license key or purchase a license key from the licensing page.
The remaining code examples in this tutorial assume that a license key has been applied in a separate config.js file, which is imported at the top of each script:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/config-import.js
import { PdfDocument } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// ...//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/config-import.js
import { PdfDocument } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// ...
Obtain a license key at ironpdf.com/nodejs/licensing/ to generate PDF documents without watermarks.
How Do You Convert HTML to PDF in Node.js? {#convert-html-to-pdf}
The IronPDF Node.js library provides four approaches for creating PDF files from HTML content:
- From a string of HTML code
- From a local HTML file
- From an online URL
- From a compressed ZIP archive
Each approach uses the PdfDocument class as its foundation. A PdfDocument represents a PDF file produced from some source content and drives most of IronPDF's core creation and editing features.
How Do You Create a PDF from an HTML String? {#create-pdf-from-html-string}
PdfDocument.fromHtml generates PDFs from strings of raw HTML markup. This approach offers the most flexibility of the four methods because the HTML string can be sourced from virtually anywhere — text files, data streams, an HTML template engine, or dynamically constructed markup.
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/html-string-to-pdf.js
import { PdfDocument } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Create a PDF from an HTML string
const pdf = await PdfDocument.fromHtml("<h1>Hello from IronPDF!</h1>");
// Save the PDF document to the file system
await pdf.saveAs("html-string-to-pdf.pdf");//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/html-string-to-pdf.js
import { PdfDocument } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Create a PDF from an HTML string
const pdf = await PdfDocument.fromHtml("<h1>Hello from IronPDF!</h1>");
// Save the PDF document to the file system
await pdf.saveAs("html-string-to-pdf.pdf");PdfDocument.fromHtml returns a Promise that resolves to an instance of the PdfDocument class. After obtaining the instance, call saveAs with a target file path to write the PDF to disk. The saved PDF file renders the HTML exactly as a standards-compliant browser would display it.
The PDF generated from the HTML string <h1>Hello from IronPDF!</h1>. The PDF files that PdfDocument.fromHtml generates appear just as web page content would appear.
How Do You Create a PDF from an HTML File? {#create-pdf-from-html-file}
PdfDocument.fromHtml also accepts a path to a local HTML document. Instead of a string of markup, pass a valid file path as the first argument. This is the preferred approach when working with saved web pages that reference local CSS, JavaScript, and image assets.
The following example converts a sample web page into a PDF:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/html-file-to-pdf.js
import { PdfDocument } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Render a PDF from a local HTML file
const pdf = await PdfDocument.fromHtml("./sample2.html");
// Save the PDF document to the project directory
await pdf.saveAs("html-file-to-pdf-1.pdf");//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/html-file-to-pdf.js
import { PdfDocument } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Render a PDF from a local HTML file
const pdf = await PdfDocument.fromHtml("./sample2.html");
// Save the PDF document to the project directory
await pdf.saveAs("html-file-to-pdf-1.pdf");
The sample HTML page as it appears in Google Chrome. Download this and similar pages from the File Samples website: https://filesamples.com/samples/code/html/sample2.html
IronPDF preserves the appearance of the original HTML document and retains the functionality of links, forms, and other interactive elements. This fidelity extends to complex pages that include paragraphs, lists, images, hyperlinks, and client-side scripting.
This PDF was generated from the HTML file example above. Compare its appearance with the previous image — IronPDF preserves the layout with high fidelity.
IronPDF handles pages that go far beyond simple markup. The following example converts a feature-rich page that sources numerous external CSS files, images, and script assets:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/html-complex-file-to-pdf.js
import { PdfDocument } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Render a PDF from a complex HTML page with external assets
PdfDocument.fromHtml("./sample4.html").then(async (pdf) => {
return await pdf.saveAs("html-file-to-pdf-2.pdf");
});//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/html-complex-file-to-pdf.js
import { PdfDocument } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Render a PDF from a complex HTML page with external assets
PdfDocument.fromHtml("./sample4.html").then(async (pdf) => {
return await pdf.saveAs("html-file-to-pdf-2.pdf");
});
If it looks good in Google Chrome, it will look good when converted to PDF. This includes CSS-heavy and JavaScript-rendered page designs.
How Do You Create a PDF from a URL? {#create-pdf-from-url}
PdfDocument.fromUrl fetches and renders a live web page as a PDF. Pass any publicly accessible URL as the argument. IronPDF's Chrome rendering engine retrieves the page, loads all assets, and produces a pixel-perfect PDF — no manual HTML download required.
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/url-to-pdf.js
import { PdfDocument } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Convert a live web page to a PDF
const pdf = await PdfDocument.fromUrl("https://en.wikipedia.org/wiki/PDF");
// Save the document
await pdf.saveAs("url-to-pdf.pdf");//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/url-to-pdf.js
import { PdfDocument } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Convert a live web page to a PDF
const pdf = await PdfDocument.fromUrl("https://en.wikipedia.org/wiki/PDF");
// Save the document
await pdf.saveAs("url-to-pdf.pdf");
The Wikipedia article about the PDF format, as it appears in a standards-compliant web browser.
The PDF generated from calling PdfDocument.fromUrl on a Wikipedia article. Note its close resemblance to the original web page.
ChromePdfRenderOptions.How Do You Create a PDF from a Zip Archive? {#create-pdf-from-zip}
PdfDocument.fromZip converts a specific HTML file contained in a ZIP archive into a PDF. This is particularly useful when distributing self-contained HTML projects that bundle their HTML, CSS, and image assets together.
For this example, assume the project directory contains a ZIP file with the following structure:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/zip-structure.txt
html-zip.zip
├─ index.html
├─ style.css
├─ logo.pngThe index.html file contains:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Hello world!</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Hello from IronPDF!</h1>
<a href="https://ironpdf.com/nodejs/">
<img src="logo.png" alt="IronPDF for Node.js">
</a>
</body>
</html>//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Hello world!</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Hello from IronPDF!</h1>
<a href="https://ironpdf.com/nodejs/">
<img src="logo.png" alt="IronPDF for Node.js">
</a>
</body>
</html>And style.css declares the page layout and font rules:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/style.css
@font-face {
font-family: 'Gotham-Black';
src: url('gotham-black-webfont.eot?') format('embedded-opentype'),
url('gotham-black-webfont.woff2') format('woff2'),
url('gotham-black-webfont.woff') format('woff'),
url('gotham-black-webfont.ttf') format('truetype'),
url('gotham-black-webfont.svg') format('svg');
font-weight: normal;
font-style: normal;
font-display: swap;
}
body {
display: flex;
flex-direction: column;
justify-content: center;
margin-left: auto;
margin-right: auto;
margin-top: 200px;
margin-bottom: auto;
color: white;
background-color: black;
text-align: center;
font-family: "Helvetica"
}
h1 {
font-family: "Gotham-Black";
margin-bottom: 70px;
font-size: 32pt;
}
img {
width: 400px;
height: auto;
}
p {
text-decoration: underline;
font-size: smaller;
}
The sample image inside the hypothetical HTML ZIP file.
When calling fromZip, specify the path to the ZIP file as the first argument and a configuration object as the second. Set the mainHtmlFile property to the name of the HTML file inside the archive that should be converted:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/zip-to-pdf.js
import { PdfDocument } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Convert an HTML file from a ZIP archive to PDF
PdfDocument.fromZip("./html-zip.zip", {
mainHtmlFile: "index.html"
}).then(async (pdf) => {
return await pdf.saveAs("html-zip-to-pdf.pdf");
});//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/zip-to-pdf.js
import { PdfDocument } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Convert an HTML file from a ZIP archive to PDF
PdfDocument.fromZip("./html-zip.zip", {
mainHtmlFile: "index.html"
}).then(async (pdf) => {
return await pdf.saveAs("html-zip-to-pdf.pdf");
});
PDF creation using PdfDocument.fromZip. The function successfully renders the HTML code from the ZIP file along with its bundled assets.
What Advanced Rendering Options Does IronPDF Support? {#advanced-rendering-options}
The ChromePdfRenderOptions interface exposes properties for granular customization of PDF rendering behavior. These settings apply before the PDF is generated and cover layout, visual appearance, and edge cases for dynamic content.
IronPDF applies default rendering settings to every conversion. Retrieve these default values with the defaultChromePdfRenderOptions function:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/default-options.js
import { defaultChromePdfRenderOptions } from "@ironsoftware/ironpdf";
// Retrieve a ChromePdfRenderOptions object with default settings
var options = defaultChromePdfRenderOptions();//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/default-options.js
import { defaultChromePdfRenderOptions } from "@ironsoftware/ironpdf";
// Retrieve a ChromePdfRenderOptions object with default settings
var options = defaultChromePdfRenderOptions();Modify the returned object's properties as needed and pass it to the renderOptions parameter of any conversion method.
How Do You Add Headers and Footers? {#add-headers-footers}
The textHeader and textFooter properties affix custom text-based content to every page of a newly rendered PDF. The following example creates a PDF from the Google search homepage with a custom header and footer, each using a different font:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/custom-headers-footers.js
import { PdfDocument, defaultChromePdfRenderOptions, AffixFonts } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Start from default render options
var options = defaultChromePdfRenderOptions();
// Configure a text-based header
options.textHeader = {
centerText: "https://www.adobe.com",
dividerLine: true,
font: AffixFonts.CourierNew,
fontSize: 12,
leftText: "URL to PDF"
};
// Configure a text-based footer
options.textFooter = {
centerText: "IronPDF for Node.js",
dividerLine: true,
fontSize: 14,
font: AffixFonts.Helvetica,
rightText: "HTML to PDF in Node.js"
};
// Render the page with custom headers and footers applied
PdfDocument.fromUrl("https://www.google.com/", { renderOptions: options }).then(async (pdf) => {
return await pdf.saveAs("add-custom-headers-footers-1.pdf");
});//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/custom-headers-footers.js
import { PdfDocument, defaultChromePdfRenderOptions, AffixFonts } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Start from default render options
var options = defaultChromePdfRenderOptions();
// Configure a text-based header
options.textHeader = {
centerText: "https://www.adobe.com",
dividerLine: true,
font: AffixFonts.CourierNew,
fontSize: 12,
leftText: "URL to PDF"
};
// Configure a text-based footer
options.textFooter = {
centerText: "IronPDF for Node.js",
dividerLine: true,
fontSize: 14,
font: AffixFonts.Helvetica,
rightText: "HTML to PDF in Node.js"
};
// Render the page with custom headers and footers applied
PdfDocument.fromUrl("https://www.google.com/", { renderOptions: options }).then(async (pdf) => {
return await pdf.saveAs("add-custom-headers-footers-1.pdf");
});
A PDF generated from the Google home page with a custom text header and footer applied using textHeader and textFooter.
For richer header and footer layouts, use the htmlHeader and htmlFooter properties instead. These accept raw HTML fragments, giving full control over typography, images, and alignment. The example below centers the page URL in bold in the header and embeds a logo image in the footer:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/html-headers-footers.js
import { PdfDocument, defaultChromePdfRenderOptions } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Start from default render options
var options = defaultChromePdfRenderOptions();
// Define a rich HTML header
options.htmlHeader = {
htmlFragment: "<strong>https://www.google.com/</strong>",
dividerLine: true,
dividerLineColor: "blue",
loadStylesAndCSSFromMainHtmlDocument: true,
};
// Define a rich HTML footer with a logo
options.htmlFooter = {
htmlFragment: "<img src='logo.png' alt='IronPDF for Node.js' style='display: block; width: 150px; height: auto; margin-left: auto; margin-right: auto;'>",
dividerLine: true,
loadStylesAndCSSFromMainHtmlDocument: true
};
// Apply custom HTML headers and footers during rendering
await PdfDocument.fromUrl("https://www.google.com/", { renderOptions: options }).then(async (pdf) => {
return await pdf.saveAs("add-html-headers-footers.pdf");
});//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/html-headers-footers.js
import { PdfDocument, defaultChromePdfRenderOptions } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Start from default render options
var options = defaultChromePdfRenderOptions();
// Define a rich HTML header
options.htmlHeader = {
htmlFragment: "<strong>https://www.google.com/</strong>",
dividerLine: true,
dividerLineColor: "blue",
loadStylesAndCSSFromMainHtmlDocument: true,
};
// Define a rich HTML footer with a logo
options.htmlFooter = {
htmlFragment: "<img src='logo.png' alt='IronPDF for Node.js' style='display: block; width: 150px; height: auto; margin-left: auto; margin-right: auto;'>",
dividerLine: true,
loadStylesAndCSSFromMainHtmlDocument: true
};
// Apply custom HTML headers and footers during rendering
await PdfDocument.fromUrl("https://www.google.com/", { renderOptions: options }).then(async (pdf) => {
return await pdf.saveAs("add-html-headers-footers.pdf");
});
IronPDF supports HTML-based headers and footers, giving full control over branding and layout on every page.
How Do You Control Page Size, Orientation, and Margins? {#page-size-orientation-margins}
The margin, paperSize, fitToPaperMode, paperOrientation, and grayScale properties on ChromePdfRenderOptions control the physical layout of every rendered page. The following example converts the Google homepage with custom margins, A5 landscape orientation, and grayscale output:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/page-size-orientation.js
import { PdfDocument, defaultChromePdfRenderOptions, PaperSize, FitToPaperModes, PdfPaperOrientation } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Start from default render options
var options = defaultChromePdfRenderOptions();
// Set page margins in millimeters
options.margin = {
top: 50,
bottom: 50,
left: 60,
right: 60
};
// Configure paper size, fit mode, orientation, and color mode
options.paperSize = PaperSize.A5;
options.fitToPaperMode = FitToPaperModes.FitToPage;
options.paperOrientation = PdfPaperOrientation.Landscape;
options.grayScale = true;
// Render with the customized layout settings
PdfDocument.fromUrl("https://www.google.com/", { renderOptions: options }).then(async (pdf) => {
return await pdf.saveAs("set-margins-and-page-size.pdf");
});//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/page-size-orientation.js
import { PdfDocument, defaultChromePdfRenderOptions, PaperSize, FitToPaperModes, PdfPaperOrientation } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Start from default render options
var options = defaultChromePdfRenderOptions();
// Set page margins in millimeters
options.margin = {
top: 50,
bottom: 50,
left: 60,
right: 60
};
// Configure paper size, fit mode, orientation, and color mode
options.paperSize = PaperSize.A5;
options.fitToPaperMode = FitToPaperModes.FitToPage;
options.paperOrientation = PdfPaperOrientation.Landscape;
options.grayScale = true;
// Render with the customized layout settings
PdfDocument.fromUrl("https://www.google.com/", { renderOptions: options }).then(async (pdf) => {
return await pdf.saveAs("set-margins-and-page-size.pdf");
});The PaperSize enumeration includes standard paper sizes such as A4, A5, Letter, and Legal. The PdfPaperOrientation enumeration supports Portrait and Landscape. These settings give precise control over output dimensions for print-ready documents.
How Do You Handle Dynamic Web Pages? {#dynamic-web-pages}
Pages that load content asynchronously — through JavaScript timers, lazy loading, or API calls — may not be fully rendered by the time IronPDF's engine captures them. The WaitFor mechanism, configured through the waitFor property on ChromePdfRenderOptions, instructs the Chrome renderer to pause until specified conditions are met before capturing the page.
The following code block sets IronPDF to wait 20 seconds before capturing the page content:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/waitfor-delay.js
import { PdfDocument, defaultChromePdfRenderOptions, WaitForType } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Configure the renderer to wait 20 seconds before capturing
var options = defaultChromePdfRenderOptions();
options.waitFor = {
type: WaitForType.RenderDelay,
delay: 20000
};
PdfDocument.fromUrl("https://ironpdf.com/nodejs/", { renderOptions: options }).then(async (pdf) => {
return await pdf.saveAs("waitfor-renderdelay.pdf");
});//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/waitfor-delay.js
import { PdfDocument, defaultChromePdfRenderOptions, WaitForType } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Configure the renderer to wait 20 seconds before capturing
var options = defaultChromePdfRenderOptions();
options.waitFor = {
type: WaitForType.RenderDelay,
delay: 20000
};
PdfDocument.fromUrl("https://ironpdf.com/nodejs/", { renderOptions: options }).then(async (pdf) => {
return await pdf.saveAs("waitfor-renderdelay.pdf");
});Alternatively, configure IronPDF to wait until a specific DOM element appears before rendering. This is useful for pages where content is injected after a JavaScript framework finishes mounting:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/waitfor-element.js
import { PdfDocument, defaultChromePdfRenderOptions, WaitForType } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Configure the renderer to wait for a specific DOM element (up to 20 seconds)
var options = defaultChromePdfRenderOptions();
options.waitFor = {
type: WaitForType.HtmlElement,
htmlQueryStr: "div.ProseMirror",
maxWaitTime: 20000,
};
PdfDocument.fromUrl("https://app.surferseo.com/drafts/s/V7VkcdfgFz-dpkldsfHDGFFYf4jjSvvjsdf", { renderOptions: options }).then(async (pdf) => {
return await pdf.saveAs("waitfor-htmlelement.pdf");
});//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/waitfor-element.js
import { PdfDocument, defaultChromePdfRenderOptions, WaitForType } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
// Configure the renderer to wait for a specific DOM element (up to 20 seconds)
var options = defaultChromePdfRenderOptions();
options.waitFor = {
type: WaitForType.HtmlElement,
htmlQueryStr: "div.ProseMirror",
maxWaitTime: 20000,
};
PdfDocument.fromUrl("https://app.surferseo.com/drafts/s/V7VkcdfgFz-dpkldsfHDGFFYf4jjSvvjsdf", { renderOptions: options }).then(async (pdf) => {
return await pdf.saveAs("waitfor-htmlelement.pdf");
});The WaitForType.HtmlElement strategy uses a standard CSS query selector. The renderer polls for the element's presence until maxWaitTime milliseconds elapse or the element is found — whichever comes first.
How Do You Generate PDFs from an HTML Template? {#html-template-to-pdf}
A common real-world automation pattern is generating a batch of PDFs from a shared HTML template, substituting placeholder values with data from a database, API, or spreadsheet. IronPDF's replaceText method on PdfDocument handles this directly.
The sample invoice template below (adapted from a publicly accessible CodePen invoice template) uses curly-brace placeholders such as {COMPANY-NAME}, {FULL-NAME}, and {INVOICE-NUMBER} for substitutable content:
A sample invoice template with placeholder tags. JavaScript code will replace each tag with real data before the document is saved as a PDF.
The following code loads the template, replaces every placeholder with test data, and saves the result as a PDF:
//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/html-template-to-pdf.js
import { PdfDocument } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
/**
* Loads an HTML template from the file system as a PdfDocument.
*/
async function getTemplateHtml(fileLocation) {
return PdfDocument.fromHtml(fileLocation);
}
/**
* Saves a PdfDocument to the specified file path.
*/
async function generatePdf(pdf, location) {
return pdf.saveAs(location);
}
/**
* Replaces a named placeholder in the PdfDocument with a data value.
*/
async function addTemplateData(pdf, key, value) {
return pdf.replaceText(key, value);
}
// Path to the HTML invoice template
const template = "./sample-invoice.html";
// Load the template, fill in all placeholder values, then save the PDF
getTemplateHtml(template).then(async (doc) => {
await addTemplateData(doc, "{FULL-NAME}", "Lizbeth Presland");
await addTemplateData(doc, "{ADDRESS}", "678 Manitowish Alley, Portland, OG");
await addTemplateData(doc, "{PHONE-NUMBER}", "(763) 894-4345");
await addTemplateData(doc, "{INVOICE-NUMBER}", "787");
await addTemplateData(doc, "{INVOICE-DATE}", "August 28, 2023");
await addTemplateData(doc, "{AMOUNT-DUE}", "13,760.13");
await addTemplateData(doc, "{RECIPIENT}", "Celestyna Farmar");
await addTemplateData(doc, "{COMPANY-NAME}", "BrainBook");
await addTemplateData(doc, "{TOTAL}", "13,760.13");
await addTemplateData(doc, "{AMOUNT-PAID}", "0.00");
await addTemplateData(doc, "{BALANCE-DUE}", "13,760.13");
await addTemplateData(doc, "{ITEM}", "Training Sessions");
await addTemplateData(doc, "{DESCRIPTION}", "60 Minute instruction");
await addTemplateData(doc, "{RATE}", "3,440.03");
await addTemplateData(doc, "{QUANTITY}", "4");
await addTemplateData(doc, "{PRICE}", "13,760.13");
return doc;
}).then(async (doc) => await generatePdf(doc, "html-template-to-pdf.pdf"));//:path=/static-assets/ironpdf-nodejs/content-code-examples/tutorials/html-to-pdf/html-template-to-pdf.js
import { PdfDocument } from "@ironsoftware/ironpdf";
import './config.js'; // Import the configuration script
/**
* Loads an HTML template from the file system as a PdfDocument.
*/
async function getTemplateHtml(fileLocation) {
return PdfDocument.fromHtml(fileLocation);
}
/**
* Saves a PdfDocument to the specified file path.
*/
async function generatePdf(pdf, location) {
return pdf.saveAs(location);
}
/**
* Replaces a named placeholder in the PdfDocument with a data value.
*/
async function addTemplateData(pdf, key, value) {
return pdf.replaceText(key, value);
}
// Path to the HTML invoice template
const template = "./sample-invoice.html";
// Load the template, fill in all placeholder values, then save the PDF
getTemplateHtml(template).then(async (doc) => {
await addTemplateData(doc, "{FULL-NAME}", "Lizbeth Presland");
await addTemplateData(doc, "{ADDRESS}", "678 Manitowish Alley, Portland, OG");
await addTemplateData(doc, "{PHONE-NUMBER}", "(763) 894-4345");
await addTemplateData(doc, "{INVOICE-NUMBER}", "787");
await addTemplateData(doc, "{INVOICE-DATE}", "August 28, 2023");
await addTemplateData(doc, "{AMOUNT-DUE}", "13,760.13");
await addTemplateData(doc, "{RECIPIENT}", "Celestyna Farmar");
await addTemplateData(doc, "{COMPANY-NAME}", "BrainBook");
await addTemplateData(doc, "{TOTAL}", "13,760.13");
await addTemplateData(doc, "{AMOUNT-PAID}", "0.00");
await addTemplateData(doc, "{BALANCE-DUE}", "13,760.13");
await addTemplateData(doc, "{ITEM}", "Training Sessions");
await addTemplateData(doc, "{DESCRIPTION}", "60 Minute instruction");
await addTemplateData(doc, "{RATE}", "3,440.03");
await addTemplateData(doc, "{QUANTITY}", "4");
await addTemplateData(doc, "{PRICE}", "13,760.13");
return doc;
}).then(async (doc) => await generatePdf(doc, "html-template-to-pdf.pdf"));The code above defines three async helper functions:
getTemplateHtml: Loads an HTML file into aPdfDocumentobject usingPdfDocument.fromHtml.addTemplateData: CallsPdfDocument.replaceTextto substitute a placeholder key with its real data value.generatePdf: Writes the completedPdfDocumentto a target file path.
Each replaceText call operates directly on the in-memory PDF representation, so multiple replacements can be chained without reloading the document from disk. The resulting PDF retains all CSS styles, fonts, and layout from the original template.
The completed PDF invoice with placeholder values replaced by real data. The CSS styles and layout from the original template are preserved exactly.
This approach scales well for batch document generation. Call getTemplateHtml once per record to create a fresh PdfDocument for each output file, then chain the addTemplateData calls for that record's data before calling generatePdf.
What Are the Next Steps? {#next-steps}
This tutorial covers the core HTML-to-PDF conversion methods and the most frequently used rendering options in IronPDF for Node.js. The topics below extend what you have learned here into more specialized areas.
- Edit and Stamp PDFs in Node.js — Apply stamps, annotations, and text edits to existing PDF documents programmatically.
- Merge and Split PDFs in Node.js — Combine multiple PDFs into a single document or split one PDF into separate pages.
- Add Watermarks to PDFs in Node.js — Apply text or image watermarks across every page of a PDF with precise positioning control.
- IronPDF Node.js API Reference — Browse the full API for
PdfDocument,ChromePdfRenderOptions,WaitFor,AffixFonts, and all other exported classes and interfaces. - Get a Free Trial License Key — Generate production-quality PDFs without watermarks by activating a free 30-day trial license.
Frequently Asked Questions
How do you convert HTML to PDF in Node.js?
Use the IronPDF library. Install it with npm install @ironsoftware/ironpdf, then call PdfDocument.fromHtml with an HTML string or file path, or PdfDocument.fromUrl with a web address. Save the result with PdfDocument.saveAs.
How do you convert an HTML string to PDF in Node.js?
Call PdfDocument.fromHtml with the HTML string as the argument. The method returns a Promise that resolves to a PdfDocument instance. Chain saveAs on the result to write the PDF to disk.
How do you convert a local HTML file to PDF in Node.js?
Pass a valid file system path to PdfDocument.fromHtml instead of an HTML string. IronPDF resolves relative CSS, image, and script paths the same way a browser would when loading the file.
How do you convert a URL to PDF in Node.js?
Call PdfDocument.fromUrl with the target URL. IronPDF fetches the page using its Chrome rendering engine and produces a pixel-perfect PDF. The target URL must be publicly accessible from the host running IronPDF.
How do you add headers and footers to a PDF in Node.js?
Set the textHeader and textFooter properties on a ChromePdfRenderOptions object for simple text headers and footers. For richer layouts, use htmlHeader and htmlFooter with raw HTML fragments. Pass the options object to the renderOptions parameter of any conversion method.
How do you change the page size and orientation in IronPDF for Node.js?
Set options.paperSize to a value from the PaperSize enum (such as PaperSize.A4 or PaperSize.Letter) and set options.paperOrientation to PdfPaperOrientation.Portrait or PdfPaperOrientation.Landscape. Pass the configured options to the conversion method.
How do you handle dynamic JavaScript content when converting to PDF?
Use the waitFor property on ChromePdfRenderOptions. Set type to WaitForType.RenderDelay and provide a delay in milliseconds, or set type to WaitForType.HtmlElement and provide a CSS query selector. IronPDF will pause rendering until the condition is satisfied.
How do you convert an HTML file inside a ZIP archive to PDF?
Call PdfDocument.fromZip with the path to the ZIP file as the first argument and an options object as the second. Set the mainHtmlFile property to the name of the HTML file inside the archive that should be converted.
How do you remove the IronPDF watermark from generated PDFs?
Apply a valid license key to the global configuration before calling any conversion method. Retrieve the config object with IronPdfGlobalConfig.getConfig() and set config.licenseKey to your key. A free trial license is available at ironpdf.com.
How do you generate PDFs from an HTML template in Node.js?
Load the template with PdfDocument.fromHtml, then call PdfDocument.replaceText for each placeholder in the template, passing the placeholder string and its replacement value. After all substitutions are complete, call saveAs to write the final PDF.





