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

Use wkhtmltoimage’s JavaScript wait controls, not just its JavaScript switch. JavaScript is enabled by default in the documented renderer. For asynchronous page setup, add a fixed --javascript-delay in milliseconds or have the page set window.status to a value passed with --window-status. IMGKit is only the Ruby wrapper; the wkhtmltoimage executable it invokes determines the actual rendering behavior.

This guide shows the command-line, IMGKit, and C-binding configurations, then provides a diagnostic sequence for pages that still capture too early.

How the rendering layers fit together

IMGKit converts Ruby calls into wkhtmltoimage options. The binary loads the HTML, runs its JavaScript, waits according to its settings, and writes the image. Consequently, changing Ruby code cannot fix a missing or unexpected renderer binary. First establish exactly which executable IMGKit runs and inspect that executable’s version and help output.

IMGKit’s README says to specify the binary when it is not in the expected location and documents passing JavaScript files with kit.javascripts. Its options are passed through to wkhtmltoimage, although the exact Ruby syntax for individual options can differ between IMGKit releases. Confirm the interface in the version installed in your application.

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

Choose a JavaScript readiness strategy

Method How it works Best use Trade-off
--javascript-delay <msec> Waits a fixed period after page loading before capture. Pages with a predictable startup time that you cannot modify. Too short produces an incomplete image; too long wastes time.
--window-status <value> Waits until the page sets window.status to the exact value. Pages you control, where an application can signal completion. Requires reliable page code and matching spelling and case.
Renderer diagnostics --debug-javascript reports script errors; --run-script runs supplied script code. Separating “script did not run” from “capture happened too soon.” Diagnostics do not add waiting by themselves.

These controls address timing. They do not guarantee that every modern browser API, framework, font, codec, or network behavior is supported by your particular wkhtmltoimage build.

Command-line configuration

Fixed delay

Enable JavaScript explicitly and wait 1.5 seconds:

wkhtmltoimage --enable-javascript --javascript-delay 1500 input.html output.png

1500 is only an example. Measure the page’s normal startup time and add margin for the slowest environment you support. The option is documented in milliseconds.

Readiness signal with window.status

Have the page signal completion after its asynchronous work has actually updated the DOM:

<script>
(async function () {
  await loadDashboardData();
  renderDashboard();
  window.status = 'rendered';
})();
</script>

Then wait for that exact value:

wkhtmltoimage --enable-javascript --window-status rendered input.html output.png

The string must match exactly. Set it only after data, templates, and visual changes needed in the screenshot are complete. If a promise can reject, add error handling that records a useful diagnostic rather than silently leaving the renderer waiting.

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.

Use a minimal local test page

Before debugging a large application, isolate the timing behavior:

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option
<!doctype html>
<html><body>
<div id="result">Starting</div>
<script>
  setTimeout(function () {
    document.getElementById('result').textContent = 'Ready';
    window.status = 'rendered';
  }, 500);
</script>
</body></html>

Capture it with --window-status rendered. If “Ready” appears, the renderer’s basic JavaScript and status wait work; investigate your application’s network requests or framework timing next.

Configure IMGKit in Ruby

IMGKit’s documented JavaScript-file input is exposed through kit.javascripts:

require 'imgkit'

kit = IMGKit.new('

Use the option names accepted by your IMGKit release. If a release does not accept the Ruby-style keys shown above, pass the equivalent wkhtmltoimage arguments through that release’s documented options interface. The important renderer settings are --enable-javascript, --javascript-delay, and --window-status.

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

For a status-based capture, replace the delay with the matching status option in your IMGKit configuration, and ensure the page assigns window.status = 'rendered'. Because IMGKit and wkhtmltoimage are separate layers, log the final command or inspect IMGKit’s configuration when diagnosing an option that appears to be ignored.

Verify the executable IMGKit actually uses

  1. Locate the wkhtmltoimage binary configured for your process, including any explicit IMGKit binary path.
  2. Run that exact path with its version command and --help.
  3. Confirm that the help output lists JavaScript, delay, window-status, and diagnostic options.
  4. Run the minimal local test page with the same user account, working directory, and environment as the application.
  5. Only then tune the production page’s delay or readiness signal.

A historical issue reported that --javascript-delay and --window-status appeared ineffective; that report records a fix milestone of 0.12.2.1. This is a version-specific historical report, not proof that every current or downstream package behaves identically. Treat the installed binary, not the gem version alone, as the thing to validate.

Diagnose pages that still capture too early

JavaScript was disabled upstream

Look for an explicit --disable-javascript in IMGKit configuration, a wrapper, a container entrypoint, or a shared options hash. The documented default is enabled, but an explicit disable wins. Add --enable-javascript and retest.

The delay is shorter than the real work

Network latency, slow APIs, timers, and client-side rendering can exceed a fixed delay. Increase it temporarily to prove the diagnosis, then prefer a status signal that is set after the final DOM update. A delay cannot know whether a request has failed or whether a late component is still rendering.

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

The status value never matches

Check spelling, capitalization, and assignment timing. The page must set the exact value requested by --window-status. If an exception occurs before that line, the renderer may wait indefinitely or finish according to build-specific behavior. Add visible error output and test the page without minification.

Scripts load from an inaccessible origin

Run the renderer under the same network, proxy, DNS, certificate, and authentication conditions as production. A browser session that works interactively may not be available to a headless process. If the page needs a local script, add it with IMGKit’s kit.javascripts mechanism or make the URL reachable to the renderer.

It is a renderer capability issue, not timing

If a long delay still produces missing controls, inspect JavaScript errors with --debug-javascript. Test a stripped-down page and remove framework features one at a time. “JavaScript enabled” does not mean that all APIs used by a modern application are implemented by every wkhtmltoimage build.

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

IMGKit and the binary disagree

Inspect the generated options and the executable path. A system package, container image, and developer workstation can contain different builds. Reproduce with a direct CLI invocation before changing Ruby code.

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

C-binding settings

The wkhtmltoimage C settings expose the same concepts under different names. web.enableJavascript controls whether JavaScript runs. load.jsdelay specifies the post-load wait; the documented behavior allows the wait to end when the delay expires or when JavaScript calls window.print(). This interface is useful when your application embeds the renderer directly rather than invoking the CLI or IMGKit.

Use the binding’s own versioned API documentation for object creation, error handling, and units. Do not assume a Ruby option name maps directly to a C structure field.

Reliability and performance guidance

  • Prefer deterministic readiness. A status signal usually avoids both premature captures and unnecessary waiting, provided your page controls all required asynchronous work.
  • Bound your waits. A page that never signals readiness needs an operational timeout around the rendering process so a stuck request cannot consume workers forever.
  • Keep capture pages small. Remove unrelated third-party widgets and requests where possible; they add failure and timing variability.
  • Record renderer identity. Log the binary path, version, selected delay or status value, URL, and failure reason for reproducibility.
  • Test cold and warm loads. Cached scripts and API responses can hide a race that appears on a first request or under load.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If maintaining a wkhtmltoimage binary, JavaScript timing, and compatibility is more work than your project needs, ScreenshotNeo provides a website screenshot API and MCP server. A single request returns PNG, JPEG, WebP, or PDF; use the API options to wait for a selector, delay, or network idle when those controls fit your page.

cURL (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}`);

Before capture, ScreenshotNeo can accept consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots.

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

Create a free ScreenshotNeo account to try the API with 1,000 screenshots per month and no card.

Frequently Asked Questions

Should I always use a fixed delay instead of window.status?

No. Use a fixed delay when you cannot change the page and its load time is predictable. Use window.status when you control the page and can signal completion after the final asynchronous update.

Does IMGKit execute JavaScript itself?

No. IMGKit is the Ruby wrapper; the wkhtmltoimage executable performs rendering and applies the JavaScript options.

What does window.print() have to do with the C API?

The documented C setting for load.jsdelay allows the post-load wait to end when the delay expires or JavaScript calls window.print(). This is separate from the CLI window-status mechanism.

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

Why does a screenshot remain incomplete after increasing the delay?

The cause may be a disabled script, a failed network request, an exception, an unmatched status value, or an API unsupported by the installed renderer. Use a minimal page and --debug-javascript to identify which category applies.

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.