HTML to Image in Node.js
Overview
Convert web pages and HTML documents to images from server-side Node.js code using the PDFCrowd client. Conversions run on PDFCrowd's servers. For a download button without backend code, see WebSave as Image.
Installation
This guide uses SDK 7 or later, supported on Node.js 18 and later. Install the client with npm, or see other installation options.
npm install pdfcrowd
See upgrading to SDK 7 when updating an existing installation.
Quick Start
You can run the examples below with the displayed API credentials. Update the input URLs and filenames as needed.
Importing the client
Examples use ES modules. For CommonJS, replace the import
statements with require() and place awaited operations inside an
async function.
CommonJS
const pdfcrowd = require('pdfcrowd');
TypeScript
The package includes TypeScript declarations. TypeScript infers conversion results and callback parameters from the SDK types. Use a namespace import:
import * as pdfcrowd from 'pdfcrowd';
For TypeScript compiled as CommonJS, you can also use:
import pdfcrowd = require('pdfcrowd');
When compiling a default import to CommonJS, enable esModuleInterop.
If your project needs Node.js types, see TypeScript dependency setup.
Convert a URL
Convert a web page to PNG and save it locally as example.png:
import pdfcrowd from 'pdfcrowd'; try { const client = new pdfcrowd.HtmlToImageClient("demo", "demo"); client.setOutputFormat("png"); const filePath = await client.convertUrlToFile( "https://example.com/", "example.png" ); console.log("Saved:", filePath); } catch (error) { // Handle the error in your application. console.error(String(error)); }
import pdfcrowd from 'pdfcrowd'; try { const client = new pdfcrowd.HtmlToImageClient("demo", "demo"); client.setOutputFormat("png"); client.convertUrlToFile( "https://example.com/", "example.png", (error, filePath) => { if (error) { // Handle the error in your application. console.error(error.toString()); return; } console.log("Saved:", filePath); } ); } catch (error) { // Handle the error in your application. console.error(String(error)); }
The output file is ready after await completes successfully,
or when the file callback runs without an error.
Handle failures as shown in Handle Errors.
Convert an HTML File
Upload document.html and save the converted PNG locally as
document.png:
import pdfcrowd from 'pdfcrowd'; try { const client = new pdfcrowd.HtmlToImageClient("demo", "demo"); client.setOutputFormat("png"); const filePath = await client.convertFileToFile( "document.html", "document.png" ); console.log("Saved:", filePath); } catch (error) { // Handle the error in your application. console.error(String(error)); }
import pdfcrowd from 'pdfcrowd'; try { const client = new pdfcrowd.HtmlToImageClient("demo", "demo"); client.setOutputFormat("png"); client.convertFileToFile( "document.html", "document.png", (error, filePath) => { if (error) { // Handle the error in your application. console.error(error.toString()); return; } console.log("Saved:", filePath); } ); } catch (error) { // Handle the error in your application. console.error(String(error)); }
For HTML that references local images or stylesheets, see Include Local Assets. To pass an HTML string, see Send HTML Content.
Configure a Conversion
Authentication
Pass your PDFCrowd username and API key to
HtmlToImageClient.
Find your credentials on the API Keys page.
To load a protected source website, configure its website credentials, cookies, or HTTP headers separately.
Choose an Input
| Input | Method |
|---|---|
| Web page URL | convertUrlToFile() |
| HTML string | convertStringToFile() |
| Local HTML file or archive | convertFileToFile() |
URLs must be reachable from PDFCrowd's servers. For a page on
localhost, send its HTML content or upload a file.
Referenced assets must also be reachable from PDFCrowd's servers or included
in an archive.
Send HTML Content
Convert an HTML string to PNG and save it as report.png:
import pdfcrowd from 'pdfcrowd'; try { const client = new pdfcrowd.HtmlToImageClient("demo", "demo"); client.setOutputFormat("png"); const html = "<html><body><h1>Monthly Report</h1></body></html>"; const filePath = await client.convertStringToFile(html, "report.png"); console.log("Saved:", filePath); } catch (error) { // Handle the error in your application. console.error(String(error)); }
import pdfcrowd from 'pdfcrowd'; function handleError(error) { // Handle the error in your application. console.error(String(error)); } try { const client = new pdfcrowd.HtmlToImageClient("demo", "demo"); client.setOutputFormat("png"); const html = "<html><body><h1>Monthly Report</h1></body></html>"; client.convertStringToFile( html, "report.png", (error, filePath) => { if (error) { handleError(error); return; } console.log("Saved:", filePath); } ); } catch (error) { handleError(error); }
Replace html with the output of your template renderer.
For relative resource URLs, add a
<base href="https://your-site.example/"> element to the HTML head,
or use absolute URLs.
Replace https://your-site.example/ with your website's public URL.
The <base> element tells PDFCrowd where to resolve relative URLs.
For example, /static/style.css becomes
https://your-site.example/static/style.css.
PDFCrowd can also combine an HTML template with structured data; see HTML templates.
Include Local Assets
Package the HTML and its local images, CSS, and JavaScript in a
.zip, .tar.gz, or .tar.bz2 archive.
Preserve the relative paths used by the HTML.
This example packages the HTML file and its local assets from a directory named
document into document.zip, then converts the HTML
to document.png:
import pdfcrowd from 'pdfcrowd'; import AdmZip from 'adm-zip'; // npm install adm-zip try { const client = new pdfcrowd.HtmlToImageClient("demo", "demo"); client.setOutputFormat("png"); const archive = new AdmZip(); archive.addLocalFolder("document"); archive.writeZip("document.zip"); const filePath = await client.convertFileToFile("document.zip", "document.png"); console.log("Saved:", filePath); } catch (error) { // Handle the error in your application. console.error(String(error)); }
import pdfcrowd from 'pdfcrowd'; import AdmZip from 'adm-zip'; // npm install adm-zip function handleError(error) { // Handle the error in your application. console.error(String(error)); } try { const client = new pdfcrowd.HtmlToImageClient("demo", "demo"); client.setOutputFormat("png"); const archive = new AdmZip(); archive.addLocalFolder("document"); archive.writeZip("document.zip"); client.convertFileToFile( "document.zip", "document.png", (error, filePath) => { if (error) { handleError(error); return; } console.log("Saved:", filePath); } ); } catch (error) { handleError(error); }
The API automatically converts the first HTML file it finds in the archive.
If the archive contains multiple HTML files, use
setZipMainFilename() to choose which one to convert.
Add Conversion Settings
Set conversion options on the client before calling a conversion method.
For example, client.setScreenshotWidth(1280); sets the screenshot width to 1280 pixels.
Common settings are listed below. See the method reference for all available options, browse Node.js examples, or try settings in the API Playground.
| Purpose | Methods |
|---|---|
| Image format | setOutputFormat() |
| Screenshot dimensions and scaling | setScreenshotWidth(), setScreenshotHeight(), setScaleFactor() |
| Background color | setBackgroundColor() |
| Print styles and custom CSS | setUsePrintMedia(), setCustomCss() |
| JavaScript and readiness | setCustomJavascript(), setWaitForElement(), setJavascriptDelay() |
| Convert a specific element | setElementToConvert() |
The default screenshot width is 1024 pixels. When no height is set, the image uses the document height.
Handle the Result
Choose an Output
The default output format is PNG. Use setOutputFormat() with "jpg" for JPEG,
or select another supported format from the
method reference.
Match the output filename extension to the selected format.
The methods below use URL input; HTML strings and files have corresponding methods.
| Output | Async/await | Callbacks |
|---|---|---|
| Local file | convertUrlToFile() |
convertUrlToFile() |
| Buffer in memory | convertUrl() |
convertUrl() supplies a stream; collect its chunks into a Buffer. |
| Readable stream | convertUrlToStream() |
convertUrl() passes the response stream to data(stream). |
For large results, file or stream output avoids collecting the entire result in memory.
When saving a stream, wait for pipeline to finish and handle any error
before using the file. See the
stream examples.
For return values and completion rules, see Promise results and Callbacks in the reference.
This example converts a web page, collects the result in a
Buffer,
and saves it locally as example.png:
import pdfcrowd from 'pdfcrowd'; import fs from 'node:fs'; try { const client = new pdfcrowd.HtmlToImageClient("demo", "demo"); client.setOutputFormat("png"); function saveResult(result) { fs.writeFileSync("example.png", result); } const result = await client.convertUrl("https://example.com/"); saveResult(result); } catch (error) { // Handle the error in your application. console.error(String(error)); }
import pdfcrowd from 'pdfcrowd'; import fs from 'node:fs'; function handleError(error) { // Handle the error in your application. console.error(String(error)); } try { const client = new pdfcrowd.HtmlToImageClient("demo", "demo"); client.setOutputFormat("png"); function saveResult(result) { fs.writeFileSync("example.png", result); } const chunks = []; let failed = false; client.convertUrl("https://example.com/", { data: (stream) => stream.on('data', (chunk) => chunks.push(chunk)), error: (message, statusCode) => { failed = true; handleError(new pdfcrowd.Pdfcrowd.Error(message, statusCode)); }, end: () => { if (failed) return; try { saveResult(Buffer.concat(chunks)); } catch (error) { handleError(error); } } }); } catch (error) { handleError(error); }
When serving the image from a web application, use the corresponding content type,
such as image/png or image/jpeg.
Handle Errors
Use try/catch around awaited conversions. In callback mode, handle errors in
the callback and catch synchronous validation errors from the initial call.
This example converts a web page,
logging the HTTP status and reason code when available:
import pdfcrowd from 'pdfcrowd'; try { const client = new pdfcrowd.HtmlToImageClient("demo", "demo"); client.setOutputFormat("png"); const filePath = await client.convertUrlToFile( "https://example.com/", "example.png" ); console.log("Saved:", filePath); } catch (error) { // Handle the error in your application. if (error instanceof pdfcrowd.Pdfcrowd.Error) { console.error("PDFCrowd error:", error.getStatusCode(), error.getReasonCode(), error.getMessage()); } else { console.error(String(error)); } }
import pdfcrowd from 'pdfcrowd'; function handleError(error) { // Handle the error in your application. if (error instanceof pdfcrowd.Pdfcrowd.Error) { console.error("PDFCrowd error:", error.getStatusCode(), error.getReasonCode(), error.getMessage()); } else { console.error(String(error)); } } try { const client = new pdfcrowd.HtmlToImageClient("demo", "demo"); client.setOutputFormat("png"); client.convertUrlToFile( "https://example.com/", "example.png", (error, filePath) => { if (error) { handleError(error); return; } console.log("Saved:", filePath); } ); } catch (error) { handleError(error); }
For stream output, handle errors both when obtaining the stream and when consuming it.
A pipeline reports failures while reading the response or writing the destination.
Conversion errors use pdfcrowd.Pdfcrowd.Error. Local file and stream operations
can also produce native errors; check the error type before using SDK-specific methods.
See the error-object reference for status, reason, and message accessors.
The SDK error's toString() includes available status and reason codes.
Use String(error) when logging an error of either type.
Common Status Codes
| Status | What it means | What to do |
|---|---|---|
400 | Invalid input, settings, or conversion failure | Read the reason code and correct the input or settings. |
401 | Missing credentials or an inactive license | Check your username, API key, and license status. |
403 | Suspended service or no credits remaining | Check your account and available credits. |
413 | Upload exceeds the 300 MB limit | Reduce the upload size. |
429 | Request rate limit reached | Wait and reduce the rate of new requests. |
430 | Concurrent request limit reached | Allow active requests to finish before starting more. |
503 | Temporary network issue | Check your retry policy before submitting another request. |
See all status and reason codes for specific explanations and Limits and Retries for retry behavior.
For job IDs, credit usage, and other conversion details, see the reference.
Limits and Retries
Request rate and concurrency limits depend on your license. Control how quickly
your application submits conversions and how many it runs at once. A
429 response concerns request rate; a 430 response
concerns requests already in progress. The maximum upload size is 300 MB.
The maximum size for any created image is 65 megapixels. Images exceeding this size are cropped vertically to meet this limit.
The Node.js client automatically retries a request once when it receives HTTP
502 or 503. Use
setRetryCount()
to change that count, or set it to 0 to disable automatic retries.
Account for these retries when adding an application-level retry policy.
PDFCrowd stops a conversion that exceeds 60 seconds of processing time.
Reason code 323 identifies this HTML conversion timeout.
Check for slow resource downloads or long-running JavaScript. Allowing your
application to wait longer does not extend the server's processing limit.
Troubleshooting
Inspect a Conversion
This example converts a web page with debug logging enabled and logs the debug log URL when available. Use the input and settings from the conversion you are investigating.
import pdfcrowd from 'pdfcrowd'; try { const client = new pdfcrowd.HtmlToImageClient("demo", "demo"); client.setOutputFormat("png"); try { client.setDebugLog(true); await client.convertUrlToFile("https://example.com/", "example.png"); } finally { const debugLogUrl = client.getDebugLogUrl(); if (debugLogUrl) console.info("Debug log:", debugLogUrl); } } catch (error) { // Handle the error in your application. console.error(String(error)); }
import pdfcrowd from 'pdfcrowd'; function handleError(error) { // Handle the error in your application. console.error(String(error)); } try { const client = new pdfcrowd.HtmlToImageClient("demo", "demo"); client.setOutputFormat("png"); function finish(error) { if (error) handleError(error); const debugLogUrl = client.getDebugLogUrl(); if (debugLogUrl) console.info("Debug log:", debugLogUrl); } try { client.setDebugLog(true); client.convertUrlToFile("https://example.com/", "example.png", finish); } catch (error) { finish(error); } } catch (error) { handleError(error); }
The debug log includes resource-loading details, timeouts, and browser console messages. You can also find logs in your conversion history. A local or connection failure may occur before a conversion log is available.
Common Problems
| Problem | Check |
|---|---|
| Images or styles are missing | Check resource URLs and authentication. See Include Local Assets for local resources. |
| A login page appears in the output | Check the source website's authentication. |
| Dynamic content is missing | Use setWaitForElement() or setJavascriptDelay(), and inspect the debug log. |
| The image has unexpected dimensions or is cropped | Check setScreenshotWidth(), setScreenshotHeight(), and the image size limit. |
| The image needs different styling | Use setCustomCss() to hide or restyle elements. |
| The application times out before receiving a result | Check client and application timeouts. Allow for uploading the input, conversion, and downloading the result. |
For help, contact support and include any available diagnostics, the client version, and enough detail to reproduce the problem.
Upgrading to SDK 7
The methods below were removed in SDK 7. For changes to Promise and callback usage, see the general upgrade notes.
| Removed method | Replacement |
|---|---|
setUserAgent() |
setClientUserAgent().
Use the same user-agent string for SDK requests to the API. |
setUseMobileUserAgent() |
setConverterUserAgent().
Use a preset such as "latest-chrome-mobile" or a custom
user-agent string instead of a boolean. |
error.getCode() |
error.getStatusCode()
returns the HTTP status code. |