Plainwork

Plainwork / Foliokit / wkhtmltopdf --javascript-delay in Chrome

wkhtmltopdf --javascript-delay and --window-status in Chrome

If your page draws its content with JavaScript (a chart, a table filled from fetch, a template engine), wkhtmltopdf let you say "wait 2 seconds" with --javascript-delay or "wait until the page says it is done" with --window-status. Chrome has no flag with those names, and the obvious replacement can silently print a half-drawn page. We tested four ways to wait on Chromium 141 (Linux, 16 October 2026) and read each PDF back with pdftotext.

The test page

A page with a heading and a paragraph that says "static text". Two scripts run: a setTimeout of 1,500 ms that replaces the paragraph with "LATE-FILLED after 1500ms" and sets window.ready = true and window.status = "ready", and a fetch of a data: URL that appends "FETCHED hi". A correct PDF contains all three phrases.

Results in Playwright

How we waitedText in the PDFVerdict
page.goto(url), then page.pdf()static text onlyPrints before the scripts finish. No error.
page.goto(url, { waitUntil: "networkidle" })static text, FETCHED hiCaught the fetch but missed the timer. "Network idle" only watches requests, not timers.
await page.waitForFunction(() => window.ready === true)LATE-FILLED, FETCHED hiComplete. Waited 1,508 ms, the time the page needed.
await page.waitForFunction(() => window.status === "ready")LATE-FILLED, FETCHED hiComplete. This is the closest match to --window-status ready.
await page.waitForTimeout(2000)LATE-FILLED, FETCHED hiComplete, but only because 2,000 is more than 1,500. It is the literal --javascript-delay 2000, and it fails the day the data takes 2,100 ms.

Results with the plain Chrome command

We ran chrome --headless --no-sandbox --print-to-pdf=out.pdf file:///path/t.html three times:

  • No extra flag: static text and FETCHED hi. The 1,500 ms timer was missed.
  • --virtual-time-budget=500: the same, the timer was missed.
  • --virtual-time-budget=3000: all three phrases were present.

So --virtual-time-budget=N is the nearest flag to --javascript-delay N. It is a budget of virtual milliseconds that Chrome lets the page's timers and network use before it prints, not a fixed wall-clock wait. A budget lower than the page's slowest timer silently drops content, just like a short --javascript-delay did. We did not test it against a page with real network requests to a slow server.

What to put in your page instead of a delay

A fixed delay is a guess. The reliable replacement is a signal from your own code, set after the last thing is drawn:

// in the page, after the chart/table is rendered
window.status = "ready";   // same signal wkhtmltopdf's --window-status waited for

// in your Playwright script
await page.goto(url);
await page.waitForFunction(() => window.status === "ready", null, { timeout: 15000 });
await page.pdf({ path: "out.pdf", format: "A4", printBackground: true });

Give waitForFunction a timeout. We checked that if the flag is never set, it throws a TimeoutError instead of printing a half-finished PDF, which is what you want in a batch job: a failure you can see beats a bad invoice you cannot. (Playwright's default timeout is 30 seconds.)

Other wkhtmltopdf script options

  • --no-stop-slow-scripts and --debug-javascript have no Chrome flag. We did not test what Chrome does with a script that never finishes; the waitForFunction timeout above is how you protect yourself.
  • --run-script (run your own JavaScript after load) becomes await page.evaluate(...) before page.pdf().
  • --enable-javascript is on by default in Chrome. Use --disable-javascript only if you did not need scripts.

Let the translator write it

Paste your whole wkhtmltopdf command into the free command translator. It maps --window-status to waitForFunction and --javascript-delay to waitForTimeout, and tells you which options have no equivalent. Related guides: page size and margins, headers and footers, and page breaks.

Limits of this page

Tested: Chromium 141 (Playwright 1.56 build) on Linux, one local file with one timer and one data-URL fetch. Not tested: Windows or macOS, other Chrome versions, Puppeteer itself (its waitForFunction is documented to behave the same way), pages that load remote scripts or images, and wkhtmltopdf's own output (its options are described from its manual). Timings will differ on your machine.

More from the catalogue

Other small tools

See everything →