PDFCrowd JavaScript Rendering: How to Wait for Dynamic Content Before Conversion
Use PDFCrowd’s selector-based wait when your page has a readiness marker, or a fixed JavaScript delay when it does not. Includes HTTP, Node.js and CLI examples.
Use PDFCrowd’s wait_for_element when the page exposes a CSS selector that appears after the content you need is ready. If there is no dependable readiness marker, use javascript_delay to wait a fixed number of milliseconds after document load. The selector approach ties conversion to a page condition; the delay approach is simpler but requires choosing an interval that fits the page and the maximum allowed by your license.
This guide covers PDFCrowd’s HTTP API, Node.js client and command-line options, how to choose a readiness marker, what to check when content is still missing, and a browser-based alternative for screenshot captures.
1. Choose the right wait strategy
| Control | Use it when | Constraint |
|---|---|---|
wait_for_element |
A known CSS selector appears when the required content is ready. | If no matching selector appears, the conversion fails when the allowed wait limit is reached. |
javascript_delay |
You cannot identify a reliable selector and can tolerate a fixed wait. | The right duration depends on the page. The license sets the maximum. |
Prefer a marker connected to the data or component you need in the PDF. A generic page wrapper may appear before the asynchronous content has populated it. PDFCrowd’s selector search covers the main document and iframes, but a selector that never appears within the permitted time causes conversion failure. See the PDFCrowd HTTP API parameter reference for the documented behavior and limits.
2. Wait for a CSS selector over HTTP
The HTTP form parameter is wait_for_element. Pass a CSS selector that appears when the content required in the PDF is ready. For example, this request waits for #content-loaded:
curl --user "USERNAME:API_KEY" \
--form "url=https://example.com/report" \
--form "wait_for_element=#content-loaded" \
--output report.pdf \
https://api.pdfcrowd.com/convert/24.04/
Replace USERNAME:API_KEY with your PDFCrowd credentials and the URL with the page you need. Keep the credentials out of source control and logs. PDFCrowd’s HTTP guide also demonstrates this as a form field: -F 'wait_for_element=#content-loaded'.
Selectors you can use
The documented examples include an ID, class, element name, comma-separated alternatives and a descendant selector:
#main-content
.main-content
table
table, #main-content
div.user-panel.main p.article
A comma-separated selector is useful if multiple page variants have different readiness markers. Choose selectors that identify the actual content, not merely a shell that loads immediately.
3. Use a fixed JavaScript delay
When there is no stable selector to wait for, use javascript_delay. Its unit is milliseconds. PDFCrowd’s HTTP reference documents a 200 ms default and a license-defined maximum; its example uses 2000 ms. Those values are examples, not guarantees that a particular page has finished rendering.
curl --user "USERNAME:API_KEY" \
--form "url=https://example.com/report" \
--form "javascript_delay=2000" \
--output report.pdf \
https://api.pdfcrowd.com/convert/24.04/
Adjust the delay based on the page’s actual loading behavior, and confirm that it does not exceed your license’s maximum. A delay that is too short may capture incomplete content; one that is unnecessarily long adds time to every conversion.
4. Node.js client example
The PDFCrowd Node.js client exposes the corresponding methods as setWaitForElement(selectors) and setJavascriptDelay(delay). Install the package with npm install pdfcrowd. This CommonJS example converts a URL and writes the resulting PDF:
const fs = require('node:fs');
const pdfcrowd = require('pdfcrowd');
const client = new pdfcrowd.HtmlToPdfClient(
process.env.PDFCROWD_USERNAME,
process.env.PDFCROWD_API_KEY
);
client.setWaitForElement('#content-loaded');
// If there is no reliable marker, use this instead:
// client.setJavascriptDelay(2000);
client.convertUrl('https://example.com/report', (error, pdf) => {
if (error) {
console.error(error);
process.exitCode = 1;
return;
}
fs.writeFileSync('report.pdf', pdf);
});
Keep only the wait control that fits your page. Check the installed client’s version-specific documentation if your package uses a different method signature; PDFCrowd’s client reference documents these method names in its Node.js API guide.
5. Set a wait from the command line
PDFCrowd’s command-line reference documents -wait-for-element and -javascript-delay. Use one of these arguments with the URL conversion command supported by your installed CLI version:
# Wait for a readiness marker
pdfcrowd --username USERNAME --api-key API_KEY \
-wait-for-element '#content-loaded' \
https://example.com/report report.pdf
# Or use a fixed delay when no reliable marker exists
pdfcrowd --username USERNAME --api-key API_KEY \
-javascript-delay 2000 \
https://example.com/report report.pdf
Command-line options and positional argument syntax can vary by installed version. Check the PDFCrowd command-line reference for the exact invocation for yours.
6. What these wait controls do—and do not do
wait_for_element waits for the specified CSS selector to appear. javascript_delay waits a fixed interval after document load. Neither setting identifies whether every possible background task on a site has finished; select a condition tied to the content your PDF needs.
PDFCrowd also documents on_load_javascript, which runs a script right after document load, and custom_javascript, which can manipulate the DOM after load when the document is ready to print. These are separate controls for running or applying JavaScript. They are not interchangeable with waiting for a source-page readiness selector. Consult the HTTP API reference for available parameter details.
7. Troubleshoot missing or incomplete content
| Symptom | Likely cause | What to check |
|---|---|---|
| Conversion fails after waiting for a selector | The selector did not appear before the license-defined maximum wait. | Confirm the selector exists on the rendered page, check spelling and CSS syntax, and verify the page can load its required content. |
| The PDF is created but dynamic content is absent | The chosen marker appeared before the asynchronous content was ready, or the fixed delay was too short. | Choose a marker associated with the needed content, or increase the delay within the permitted maximum. |
| Increasing the delay does not help | The content may not be loading at all, or may rely on page requirements the request does not meet. | Inspect resource loading, timeouts and browser console details in the PDFCrowd debug log. |
| The selector works locally but not in conversion | The converted document may differ from the local browser state, or the content may require authentication or another page condition. | Check that the selector is in the converted document or an iframe PDFCrowd searches, and inspect the debug log. |
PDFCrowd’s API guide recommends wait_for_element or javascript_delay for missing dynamic content. The x-pdfcrowd-debug-log response header links to details on resource loading, timeouts and browser console messages; conversion history also contains logs. Start there when a longer wait does not resolve the issue. A page whose content is blocked, authentication-dependent or rendered outside the searched document and iframes may need investigation beyond changing the wait value.
8. Reliability, performance and cost considerations
- Reliability: A content-specific selector is easier to relate to the output you need than a guessed timer. It still depends on that selector appearing during conversion.
- Performance: A fixed delay adds its full interval to each conversion, including runs where content loads sooner. A selector wait can proceed when the marker appears, subject to the service’s wait behavior and license maximum.
- Failure handling: Treat a missing selector as a conversion error. Log the requested URL and wait setting, but avoid recording credentials or sensitive page content.
- Cost: The supplied PDFCrowd references establish the wait controls and license-defined maximum, but do not provide enough information here to state per-conversion pricing. Check your plan’s current limits and pricing before setting batch sizes or retry policies.
- Retries: Retrying a conversion will not fix a selector that never exists or a resource that remains blocked. Inspect logs and page prerequisites before retrying repeatedly.
Or skip the browser setup
If you need a rendered page capture rather than a paginated PDF, ScreenshotNeo provides a website screenshot API with a single GET request. Its options include full-page capture with lazy images loaded and PDF output. Pass the target URL and save the response:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. ScreenshotNeo accepts cookie and consent banners like a visitor and removes 60+ known consent platforms, newsletter popups and chat widgets before capture; each cleanup step can be turned off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, and responses include X-Page-Verdict and X-Billed headers. Its MCP server lets AI agents use take_screenshot, get_page_info and capture_pdf. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.
Sign up for ScreenshotNeo free: 1,000 screenshots a month, no card required.
FAQ
Can I wait for more than one possible element?
Yes. PDFCrowd’s HTTP examples include comma-separated alternatives, such as table, #main-content. Use alternatives when page variants expose different markers for the same readiness condition.
Does the selector search include iframes?
Yes. PDFCrowd documents that the search includes the main document and all iframes.
Is 2000 ms always enough?
No. It is a documented example value. The appropriate delay depends on the page and is limited by the maximum configured for your license.
Should I use custom JavaScript instead of a wait setting?
Use custom JavaScript when you need to run or apply a script to page content. Use the wait setting to delay conversion until a readiness condition or time interval is reached; these controls solve different parts of the rendering process.


