ScreenshotNeo

BlogHow-to

How to Take a Full Website Screenshot with wkhtmltoimage in WordPress

Capture a WordPress page with wkhtmltoimage, choose the right viewport and wait settings, and troubleshoot rendering differences and missing content.

By the ScreenshotNeo team4 October 20267 min read

wkhtmltoimage is a separate command-line renderer, not a WordPress screenshot feature. Run it on a machine that can reach your WordPress page, choose an output format and viewport width, and inspect the result for missing content and layout differences. A basic PNG capture is:

wkhtmltoimage --format png --width 1280 https://example.com/ page.png

Replace the example URL and width with values suited to your site. The width sets the rendering viewport; it is not a guarantee that the page will match a browser screenshot or that every site should use 1280 pixels.

1. What wkhtmltoimage does

wkhtmltoimage belongs to the wkhtmltopdf project. It is a headless command-line HTML-to-image renderer built on Qt WebKit, so it can render without a display service. WordPress serves the page; wkhtmltoimage loads that page and writes an image file. See the upstream project and its usage manual.

There is no special WordPress mode required. The page must be reachable from the machine running the command, and its linked stylesheets, scripts, fonts, and images must also be accessible. You can provide a URL or, where appropriate, an HTML file. Local-file access is controlled by the tool’s options; do not enable broad local access for untrusted HTML.

2. Install and check the command

  1. Obtain a binary appropriate for the operating system or build from source, following the project documentation.
  2. Check which binary is installed and inspect its own help output. Packages and builds can differ, so treat the installed command as authoritative for supported options.
  3. Confirm that the machine can reach the WordPress URL. For a private or staging site, arrange network access and authentication without putting credentials in shell history or publishing them in scripts.
wkhtmltoimage --version
wkhtmltoimage --help

The upstream GitHub repository is archived. For a new production workflow, verify the package source and compatibility you intend to rely on rather than assuming a particular build is current.

3. Capture a WordPress page

Use the URL of the page you want to capture and an output filename with the desired extension:

wkhtmltoimage --format png --width 1280 https://example.com/about/ about.png

For JPEG output, change the format and file extension:

wkhtmltoimage --format jpg --width 1280 https://example.com/about/ about.jpg

Check the installed binary’s help for the exact accepted format values and available options. The project manual documents the command’s settings; builds may vary.

Capture a locally saved HTML file

If you already have HTML on disk, pass its path as the input and an image path as output, subject to the local-file access rules of your build:

wkhtmltoimage --format png --width 1280 file:///absolute/path/to/page.html page.png

Relative assets in that HTML must resolve from the renderer’s environment. Keep local-file access restricted when processing HTML you do not trust.

4. Choose the viewport and wait for JavaScript

--width controls the viewport width used to lay out the page. Pick a width that represents the layout you want to inspect: a desktop width for a desktop layout, or a narrower width if you need to inspect responsive behavior. Review the resulting image at full size for clipping and unexpected wrapping.

The CLI documentation says JavaScript is enabled by default and the default JavaScript delay is 200 milliseconds. Pages that populate content asynchronously may need a longer delay. For example:

wkhtmltoimage --format png --width 1280 --javascript-delay 1500 https://example.com/ page.png

A delay only waits for a set time; it does not guarantee that every script, animation, lazy image, or network request has finished. Test the actual page. The release history notes that version 0.12.2.1 fixed an earlier issue with the JavaScript-delay and window-status options, so check behavior on the binary you have installed.

5. Check the output for common page issues

  • Lower-page content is absent: inspect whether the renderer captured the complete document and whether content is inserted only after scrolling or interaction. A viewport width alone does not force lazy content to load.
  • Images or styles are missing: verify the renderer can reach each asset URL, that the site does not require browser state or authentication for those assets, and that the machine’s network rules permit access.
  • Consent banners or popups cover content: these are part of the page unless your capture setup handles them. Review what the page displays before treating the output as a clean reference.
  • Layout differs from a modern browser: wkhtmltoimage uses Qt WebKit, whose behavior can differ from current browser engines. Test the theme and CSS you actually use.
  • Fonts or colors differ: check that remote fonts and stylesheets loaded successfully and compare the rendered image with the target page in a browser.

6. Troubleshooting

Symptom Likely cause What to try
Command not found The binary is not installed or is not on the command path. Install a compatible build, then check wkhtmltoimage --version and the command’s help.
Cannot load the page The machine cannot reach the URL, the URL is wrong, or the page requires access the command does not have. Open the URL from the same machine or environment, check network and authentication requirements, and use a reachable page URL.
Blank or incomplete image Page scripts may not have populated content yet, or required assets failed to load. Try a longer --javascript-delay, then check asset reachability and inspect the result again. Waiting is not a guarantee of completion.
Modern CSS appears broken Qt WebKit may not match the CSS support or layout behavior of a current browser. Test the exact theme and build. An archived issue reports a flex-layout discrepancy in a wkhtmltoimage 0.12.6 environment; it is a version-specific report, not proof that every build fails.
Local HTML cannot load a file Local-file access is restricted or referenced files are not at the expected paths. Check the manual and installed help for local-file controls, correct asset paths, and avoid enabling broad access for untrusted input.
Output format is rejected The requested format value may not be supported by that binary. Consult the installed command’s help and use a supported format and matching filename extension.

7. Performance, reliability, and cost

Capture time depends on the target page, network access, asset count, and JavaScript behavior. Increasing the JavaScript delay adds waiting time per capture and can still miss content that loads later or only after interaction. For repeatable captures, record the binary version, command options, input URL, viewport width, and any wait settings alongside the output.

Reliability depends on both the page and the renderer: redirects, access controls, external resources, delayed scripts, and engine compatibility can all affect the result. Inspect samples after theme or site changes. The reviewed project sources provide no WordPress-specific performance benchmark or one-size-fits-all full-page command, so estimate runtime and compatibility on your own pages.

The software workflow has no per-capture ScreenshotNeo charge, but running it still uses machine resources and requires installation and maintenance of a compatible binary. If you need a managed screenshot API instead, ScreenshotNeo’s listed plans range from 1,000 free shots per month with no card to paid plans starting at $5 for 3,000; every feature is available on every plan.

8. Or skip the browser setup

ScreenshotNeo takes a screenshot through one API request. See the API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/ -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com/"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com/' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', new Uint8Array(await res.arrayBuffer()));

Replace YOUR_API_KEY with your key. The Python example needs the requests package; the Node.js example uses the built-in fetch API and Bun’s file writer, so under plain Node.js replace the final line with import { writeFile } from 'node:fs/promises'; await writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));.

  • Cookie and consent banners are accepted and removed before capture, along with supported newsletter popups and chat widgets.
  • Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed; response headers report the page verdict and billing status.
  • An MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients.
  • 1,000 screenshots per month are free with no card; paid plans start at $5 for 3,000.

Sign up for ScreenshotNeo and get 1,000 free screenshots a month, with no card required.

9. Frequently asked questions

Does WordPress need a screenshot plugin?

No. wkhtmltoimage runs separately and loads the WordPress page by URL or suitable HTML input.

Will the result match Chrome or Firefox exactly?

Not necessarily. It renders with Qt WebKit, and CSS, scripts, and assets may behave differently from a current browser.

Is a longer JavaScript delay always better?

No. It increases the wait but cannot guarantee that content gated on scrolling, interaction, or later network events will appear.

Can I safely render arbitrary local HTML?

Local-file access is restricted by documented controls. Keep access limited when the HTML is untrusted and review the installed build’s settings.