Skip to main content
JavaScript rendering enables full browser execution to capture dynamically loaded content, handle user interactions, and process JavaScript-heavy websites. Control rendering behavior with advanced options for timeout, iframe handling, and load detection.

When to use

Use JavaScript rendering when you need to:
  • Load dynamic content: Capture content loaded via AJAX or fetch requests
  • Execute JavaScript: Process sites that require JS for content display
  • Handle SPAs: Extract data from Single Page Applications (React, Vue, Angular)
  • Wait for interactions: Capture DOM state after user actions
  • See final state: Get the page as users see it, not raw HTML
Rendering requires vx8, vx10, or vx14 drivers. The vx6 driver does not support rendering.

Supported parameters

Available in - Extract
ParameterTypeDescriptionDefault
renderBooleanEnable or disable JS renderingfalse
render_optionsObjectMax wait time in milliseconds-

Render options parameter

The render_options parameter provides fine-grained control over rendering behavior:
ParameterTypeDescriptionDefault
render_typeStringWhen to consider page “loaded”, refer to render types below to see available optionsload
timeoutIntegerMax wait time in milliseconds30000
include_iframesBooleanWhether to load iframe contentfalse
blocked_domainsArrayDomains to block from loading[]

Render types

Control when the page is considered fully loaded:
TypeDescriptionUse Case
loadWait for standard load eventDefault for most pages
domreadyWait for DOMContentLoaded eventFaster, before all resources load
idle2Wait for ≤2 network connections in last 500msDynamic content still loading
idle0Wait for 0 network connections in last 500msEnsure everything is loaded

Usage

Enable basic rendering

Set render: true to enable JavaScript execution:
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True
})

print(result)
When render: false (default), the API returns the raw HTML without JavaScript execution, suitable for static pages.

Advanced JS rendering

from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "render_options": {
        "render_type": "idle0",
        "timeout": 60000,
        "include_iframes": True,
        "blocked_domains": ["ads.example.com", "tracking.example.com"]
    }
})

print(result)

Dynamic content loading

Wait for AJAX-loaded content:
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

# Wait for all network activity to stop
result = nimble.extract({
    "url": "https://www.example.com/products",
    "render": True,
    "render_options": {
        "render_type": "idle0",
        "timeout": 45000
    }
})

print(result["data"]["html"])

Single Page Applications

Extract from React, Vue, or Angular apps:
from nimble import Nimble
from pydantic import BaseModel

class Product(BaseModel):
    name: str
    price: float
    rating: float

nimble = Nimble(api_key="YOUR-API-KEY")

# SPAs need rendering and proper wait time
result = nimble.extract({
    "url": "https://spa-example.com/products",
    "render": True,
    "render_options": {
        "render_type": "idle2",
        "timeout": 30000
    },
    "schema": Product
})

print(result["data"])

Iframe content extraction

Include iframe content in extraction:
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

# Include iframe content (e.g., embedded videos, widgets)
result = nimble.extract({
    "url": "https://www.example.com/page-with-iframes",
    "render": True,
    "render_options": {
        "include_iframes": True,
        "render_type": "load",
        "timeout": 40000
    },
    "formats": ["html"]
})

print(result["data"]["html"])

Block unnecessary resources

Improve performance by blocking ads and tracking:
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

# Block ads, analytics, and tracking domains
result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "render_options": {
        "blocked_domains": [
            "googletagmanager.com",
            "google-analytics.com",
            "facebook.com",
            "doubleclick.net",
            "ads.example.com"
        ],
        "render_type": "idle2",
        "timeout": 25000
    }
})

print(result)

Fast rendering for simple sites

Use DOMContentLoaded for faster responses:
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

# Don't wait for images/styles to load
result = nimble.extract({
    "url": "https://www.example.com/article",
    "render": True,
    "render_options": {
        "render_type": "domready",
        "timeout": 15000
    },
    "formats": ["markdown"]
})

print(result["data"]["markdown"])

Combining with browser actions

Rendering works seamlessly with browser actions:
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

# Render page, then perform actions
result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "render_options": {
        "render_type": "idle0",
        "timeout": 30000
    },
    "browser_actions": [
        {
            "wait_and_click": {
                "selector": "button.load-more",
                "timeout": 5000
            }
        },
        {
            "wait": {
                "delay": 2000
            }
        },
        {
            "infinite_scroll": {
                "duration": 5000
            }
        }
    ]
})

print(result)

Best practices

Choose the right render type

Use load for standard pages:
# ✅ Default for most websites
render_options = {
    "render_type": "load"
}
Use domready for speed:
# ✅ When images/styles aren't needed
render_options = {
    "render_type": "domready"  # Faster response
}
Use idle2 for dynamic content:
# ✅ For AJAX-heavy pages
render_options = {
    "render_type": "idle2",  # Wait for most requests to finish
    "timeout": 30000
}
Use idle0 for complete loading:
# ✅ When you need everything loaded
render_options = {
    "render_type": "idle0",  # Wait for all network activity
    "timeout": 60000  # Higher timeout for slow sites
}

Optimize timeout settings

Set appropriate timeouts:
# ❌ Too short - may miss content
render_options = {
    "render_type": "idle0",
    "timeout": 5000  # Not enough for slow sites
}

# ✅ Balanced timeout
render_options = {
    "render_type": "idle0",
    "timeout": 30000  # 30 seconds is usually sufficient
}

# ✅ Extended for slow sites
render_options = {
    "render_type": "idle0",
    "timeout": 60000  # Up to 60 seconds for very slow sites
}

Block unnecessary domains

Common domains to block:
common_blocked_domains = [
    # Analytics
    "google-analytics.com",
    "googletagmanager.com",
    "segment.com",
    "mixpanel.com",

    # Advertising
    "doubleclick.net",
    "googlesyndication.com",
    "adservice.google.com",

    # Social media widgets
    "facebook.com",
    "twitter.com",
    "linkedin.com",

    # CDN for ads
    "ads.example.com",
    "tracking.example.com"
]

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "render_options": {
        "blocked_domains": common_blocked_domains
    }
})
Benefits of blocking:
  • Faster page loads
  • Lower bandwidth usage
  • Reduced detection risk
  • Cleaner HTML output

Handle iframes carefully

Enable only when needed:
# ❌ Don't enable iframes unnecessarily
render_options = {
    "include_iframes": True  # Slower and larger response
}

# ✅ Enable only for specific content
if need_iframe_content:
    render_options = {
        "include_iframes": True,
        "timeout": 45000  # Increase timeout for iframes
    }
else:
    render_options = {
        "include_iframes": False
    }

Combine with network capture

Monitor and capture API calls during rendering:
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

# Render page and capture specific API calls
result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "render_options": {
        "render_type": "idle0",
        "timeout": 30000
    },
    "network_capture": [
        {
            "method": "GET",
            "url": {
                "type": "contains",
                "value": "/api/products"
            }
        }
    ]
})

# Access captured network data
api_responses = result["data"]["network_capture"]
print(api_responses)

Performance optimization

Choose the minimal driver:
# ❌ Don't use vx10 when vx8 works
result = nimble.extract({
    "url": "https://simple-spa.com",
    "driver": "vx10",  # Unnecessary stealth features
    "render": True
})

# ✅ Use appropriate driver
result = nimble.extract({
    "url": "https://simple-spa.com",
    "driver": "vx8",  # Sufficient for most SPAs
    "render": True
})
Monitor execution time:
result = nimble.extract({
    "url": "https://www.example.com",
    "render": True
})

# Check rendering performance
exec_time = result["metadata"]["execution_time_ms"]
print(f"Rendering took {exec_time}ms")

# Optimize if too slow
if exec_time > 10000:
    print("Consider blocking domains or changing render_type")

When to skip rendering

Use non-rendering (vx6) when:
  • Static content: HTML already contains all data
  • API endpoints: Fetching JSON directly
  • High throughput needed: Rendering is slower
  • Simple pages: No JavaScript required
  • Cost optimization: Non-rendering is cheaper
# ✅ Skip rendering for static pages
result = nimble.extract({
    "url": "https://static-site.com/page.html",
    "render": False,  # or omit (false is default)
})