October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
HTML to PDF

How to Debug JavaScript in wkhtmltopdf (Delays, Logs, Readiness Signals, and Fixes)

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Start with a reproducible command that turns on diagnostics and allows asynchronous code to finish:

wkhtmltopdf --debug-javascript --javascript-delay 1000 input.html output.pdf

Then verify that JavaScript has not been disabled, inspect the messages, and replace guesswork with a page-controlled readiness signal when possible. wkhtmltopdf enables JavaScript by default, but its older WebKit/Qt runtime and the exact binary build determine which scripts and browser APIs work.

1. Capture the exact environment first

Before changing the page, record the executable, version, input type and complete command. This distinguishes a JavaScript failure from a wrapper, package or file-access problem.

wkhtmltopdf --version
wkhtmltopdf --debug-javascript --javascript-delay 1000 https://example.com report.pdf
  • Save whether the input is an HTTPS URL, a local HTML file or generated temporary HTML.
  • Record whether a framework, container, language binding or queue invokes wkhtmltopdf.
  • Keep the full stderr output; wrappers sometimes hide renderer diagnostics.

The project documents command-line controls in its CLI usage reference and library equivalents in the libwkhtmltox settings reference.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

2. Turn on JavaScript diagnostics

Use --debug-javascript while reproducing the issue. It is documented as showing JavaScript debugging output. The inverse, --no-debug-javascript, suppresses it and is the default. Exact wording and visibility depend on the binary or library wrapper.

wkhtmltopdf --debug-javascript page.html debug.pdf 2>wkhtmltopdf.log
cat wkhtmltopdf.log

Look for syntax errors, missing variables, failed network requests, blocked resources and exceptions thrown during startup. A clean log does not prove that asynchronous rendering completed; it only means no diagnostic was emitted in the paths reached.

3. Confirm that JavaScript is enabled

The CLI enables JavaScript by default. An inherited option, wrapper setting or library configuration can still turn it off.

wkhtmltopdf --enable-javascript --debug-javascript page.html output.pdf

Remove --disable-javascript if it appears in the command. With the library API, inspect web.enableJavascript. If you control the page, add a visible test marker:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<script>
document.documentElement.setAttribute('data-js-ran', 'true');
</script>

After conversion, inspect the HTML source or a deliberately visible element in the PDF. This separates “the script never ran” from “the script ran but data was not ready.”

4. Separate timing failures from execution failures

Use a fixed delay as a diagnostic experiment

--javascript-delay <milliseconds> waits after page loading. The documented default is 200 milliseconds, which is often too short for API calls, charts, fonts or client-side rendering.

wkhtmltopdf --debug-javascript --javascript-delay 3000 page.html delayed.pdf

Try 1,000, 3,000 and 10,000 milliseconds while watching the output. If the PDF changes as the delay increases, timing is involved. A fixed delay is a heuristic: it can render too early on a slow run or waste time on a fast one, so do not treat a large number as a permanent fix without measuring your workload.

Use an explicit readiness marker

When you can edit the page, set window.status only after the required table, chart or other content is present:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<script>
async function renderReport() {
  await loadDataAndDrawChart();
  window.status = 'ready';
}
renderReport().catch(error => {
  console.error(error);
  window.status = 'render-error';
});
</script>

Invoke:

wkhtmltopdf --debug-javascript --window-status ready report.html report.pdf

The option waits for the status string before rendering. If the assignment is never reached, conversion can wait indefinitely; impose a timeout in your calling process and log a failure. Keep the error status distinct so a failed render cannot look like successful readiness.

Delay versus window status

Criterion --javascript-delay --window-status
Implementation No page changes Requires code you control
Completion signal Elapsed time only Page declares completion
Early-render risk High when load time varies Lower if the signal is correct
Latency At least the chosen delay Can finish as soon as readiness is reached
Compatibility uncertainty Simple and widely available Verify behavior in your installed build

The documentation describes both controls but does not define every interaction when they are combined. A 2015 issue report for wkhtmltopdf 0.12.2.1 described behavior that appeared to wait for the longer interval; treat that as a version-specific report, not a universal rule. Test your own binary with a page that sets status after a known delay.

5. Check scripts, resources and local-file permissions

Run controlled scripts with --run-script

--run-script <JavaScript> executes additional JavaScript after the page has loaded. It is useful for a controlled setup or a diagnostic marker, but it cannot add browser APIs that the renderer does not implement.

wkhtmltopdf --debug-javascript --run-script "document.body.dataset.probe='ok'" page.html probe.pdf

Test local resources explicitly

A local HTML file may reference scripts, styles, fonts or JSON beside it. Access controls can block those files. Use narrow permissions where needed rather than broadly enabling access:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
wkhtmltopdf --allow /srv/report-assets /srv/report.html /srv/report.pdf

Check every relative URL, case-sensitive filename and redirect. For remote resources, verify DNS, TLS, authentication and whether the endpoint serves different content to wkhtmltopdf’s user agent.

Investigate long-running code

wkhtmltopdf documents stopping slow scripts by default with --stop-slow-scripts. The inverse, --no-stop-slow-scripts, can help diagnose a script that is being interrupted, but it can also create hangs and high resource use. Use it only for a bounded reproduction.

6. Reduce the page and compare carefully

  1. Create a minimal HTML file with one script and one visible result.
  2. Add the data request, chart library or component that triggers the failure.
  3. Capture console output and the generated PDF at each step.
  4. Compare the same page in a current browser to identify unsupported APIs, but do not assume both runtimes have identical JavaScript support.
  5. Record the wkhtmltopdf and Qt build before filing or applying a workaround.

The project’s downloads and project information page notes that some capabilities require patched Qt and that distributions differ. A page working in Chrome can still fail in wkhtmltopdf because of syntax, APIs, security policies or engine limitations.

7. Common failures and targeted fixes

The PDF contains the empty shell

Cause: asynchronous work finished after the default 200 ms delay. Fix: test a longer --javascript-delay, then implement window.status after rendering.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

No JavaScript output appears

Cause: diagnostics are disabled, stderr is hidden, or the code path is never reached. Fix: add --debug-javascript, redirect stderr, verify JavaScript is enabled and add a visible marker.

The status wait never completes

Cause: an exception, failed request or conditional branch prevents the assignment. Fix: set an error status in a catch block, inspect logs and enforce an external timeout.

A modern library throws syntax or API errors

Cause: the installed WebKit/Qt build lacks a language feature or browser API used by the library. Fix: reduce the page, transpile or polyfill only what is required, or use a renderer whose engine supports the page. Do not generalize from one historical Plotly report; the issue tracker records individual failures, not universal incompatibility.

Images, fonts or data are missing from a local file

Cause: blocked local-file access or incorrect paths. Fix: use absolute, verified paths and a narrowly scoped --allow directory; check permissions and redirects.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Conversion hangs or consumes excessive CPU

Cause: an infinite loop, never-ending request or slow script. Fix: reproduce with --stop-slow-scripts, add application-level timeouts, and avoid disabling the safeguard in production unless the workload is tightly controlled.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

8. Library settings and automation

When invoking libwkhtmltox instead of the CLI, map the same concepts to settings: web.enableJavascript controls execution, load.debugJavascript forwards JavaScript warnings and errors to the callback, and load.jsdelay specifies a delay. The library documentation says load.jsdelay waits for the delay or until JavaScript calls window.print(). Confirm how your language binding names these fields and where it sends callbacks.

In CI or a queue, log the binary version, command/settings, URL, elapsed time, exit code, stderr and a timeout reason. Keep a small fixture page that sets window.status after a known interval; it detects packaging or runtime changes before they affect production reports.

9. Security considerations

The official project warns against processing untrusted HTML without sanitizing user-supplied HTML and JavaScript. A conversion service should isolate the renderer, restrict outbound network access where practical, limit CPU and memory, use temporary directories with safe permissions, and apply narrowly scoped local-file access. Treat JavaScript-capable PDF conversion as code execution, not as harmless formatting.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

If your goal is a dependable screenshot rather than a legacy WebKit PDF conversion, ScreenshotNeo provides a hosted screenshot API and MCP server. One GET request returns PNG, JPEG or WebP, while its capture pipeline accepts consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets before the shot. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result.

For a direct call, see the ScreenshotNeo documentation:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Frequently Asked Questions

What is wkhtmltopdf’s default JavaScript delay?

The documented default is 200 milliseconds. It is a renderer default, not a guarantee that asynchronous content will be ready.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can –window-status replace a delay completely?

Often, when you control the page and set the status after all required rendering finishes. Add an external timeout because a page that never reaches the assignment can wait indefinitely.

Does –run-script make unsupported browser APIs work?

No. It can run additional JavaScript, but it cannot upgrade wkhtmltopdf’s WebKit or Qt engine.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.