Sometimes, your requests may return empty or incomplete content. This is typically due to how modern websites load content dynamically using JavaScript or AJAX (XHR) calls. By default, ZenRows returns the HTML content once the DOM is initially loaded, which might not include content populated by JavaScript.

This guide provides diagnostic steps, common scenarios, and parameter configurations to help you resolve these issues and get complete, usable responses.

These troubleshooting steps are applicable across all ZenRows features, including screenshot, outputs, json_response, and others.

Why Does This Happen?

Even if a page visually “loads,” its content might still be missing because:

  • The content is rendered by JavaScript after the DOM loads.
  • The actual data is fetched via XHR (AJAX) requests.
  • The page relies on user interaction or delays to render content.
  • Anti-bot measures may serve minimal or obfuscated content.

Quick Decision Tree

ERROR

Is js_render enabled?
  ├─ No → Enable `js_render`
  └─ Yes

   Is content dynamic (loaded after a delay or via JS)?
       ├─ Yes → Use `wait` or `wait_for`
       └─ No

     Is content loaded via XHR?
            ├─ Yes → Use `json_response`
            └─ No → Enable screenshot to visually debug

        Does the page require user interaction?
                ├─ Yes → Use `js_instructions`
                └─ No → Content may be static or blocked

Parameter Reference

ParameterDescriptionRequired WhenType
js_renderEnables JavaScript rendering in a headless browserSite loads content via JSBoolean
waitWaits for a specified time in milliseconds before returning the responseSite loads slowlyInteger
wait_forWaits for a specific CSS selector to be presentSite depends on dynamic elementsString
json_responseExtracts data from XHR/Fetch calls loaded during page renderSite uses API calls for contentBoolean
js_instructionsPerforms custom user interactions (clicks, scrolls, etc.)Site requires interaction to reveal contentArray
premium_proxyUses residential proxies to avoid detection and access restricted contentSite blocks datacenter IPs or has bot detectionBoolean

1. Enable JavaScript Rendering

If the target website relies on JavaScript to display content, enable js_render. This ensures that ZenRows runs JavaScript in a headless browser to render the page fully.

params = {
    'url': url,
    'apikey': apikey,
	'js_render': 'true',
}

This parameter is required when using other advanced features such as wait, wait_for, screenshot, json_response, outputs, and others.

2. Use Wait Parameters

Some websites load content after a delay. Use the wait parameter to introduce a fixed delay or wait_for to wait for a specific CSS selector to appear.

Example with wait

params = {
    'url': url,
    'apikey': apikey,
	'js_render': 'true',
	'wait': '15000', # Waits for 15 seconds
}

Example with wait_for

params = {
    'url': url,
    'apikey': apikey,
	'js_render': 'true',
	'wait_for': '.content-loaded', # Waits for the specified CSS selector
}
wait_for will cause the request to fail if the selector is not found. Use browser DevTools to find reliable CSS selectors on your target site.

3. Use json_response for XHR-based Pages

If the data you’re trying to scrape is loaded via JavaScript through AJAX calls, you can use the json_response parameter to access the response of those internal XHR requests.

params = {
    'url': url,
    'apikey': apikey,
	'js_render': 'true',
	'wait_for': '.selector',
	'json_response': 'true',
}
Combine json_response with wait or wait_for to ensure all background requests have completed before data is captured.

4. Use Screenshot for Debugging

To understand what ZenRows actually “sees”, enable the screenshot parameter. This can help determine whether content is missing due to rendering delays or protections.

params = {
    'url': url,
    'apikey': apikey,
	'js_render': 'true',
	'wait_for': '.selector',
	'screenshot': 'true',
}   

This feature provides a rendered image of the page after all scripts have run and delays have passed.

5. Use js_instructions for Interactive Pages

If the page requires user interaction to load the content (like clicking a button, scrolling, or inputting text), use the js_instructions parameter. This allows you to simulate actions in the browser before the content is captured.

Example:

params = {
    'url': url,
    'apikey': apikey,
	'js_render': 'true',
	'js_instructions': """[
        {"click":".selector"},
        {"wait":500},
        {"fill":[".input","value"]},
        {"wait_for":".slow_selector"}
    ]""",
} 

When using js_instructions, each instruction can have an optional wait_for step. If the selector is not found, ZenRows will attempt the next instruction after a short delay.

Mixing Steps for Advanced Debugging

You can combine multiple steps for complex scenarios. For example:

  • Use js_instructions to simulate user interactions, followed by json_response to capture XHR data.
  • Enable screenshot alongside wait_for to visually confirm dynamic content.

Example:

params = {
    'url': url,
    'apikey': apikey,
	'js_render': 'true',
	'js_instructions': """[
        {"click":".selector"},
        {"wait":500},
        {"fill":[".input","value"]},
        {"wait_for":".slow_selector"}
    ]""",
    'json_response': 'true',
} 

Summary Table

ScenarioRecommended ParametersNotes
Empty or partially loaded pagesjs_render=trueEnsures JavaScript runs to render dynamic content
Content loads slowlywait=5000 or wait_for=.selectorAllows time for content to appear or specific element to load
Page requires user interactionjs_instructions=[{"click":".selector"}...]Simulates user actions like dismissing modals or clicking buttons
Data comes from background requestsjson_response=true + wait or wait_forCaptures XHR/Fetch data loaded after DOM is ready
Complex sites with strong protectionpremium_proxy=true + js_render=trueMimics real browser with rotating residential IPs

Still Stuck?

If you’re still getting empty or partial responses after following the steps above:

  1. Double-check your CSS selectors in DevTools
  2. Use a screenshot to confirm what ZenRows is rendering
  3. Reach out to support at success@zenrows.com with:
    • Your full request URL.
    • Parameters used.
    • Expected vs actual response.
    • What you’ve already tested.
    • Any other useful information, such as specific errors or observations.

Our team will help you optimize your request for better results.