Many modern websites load content dynamically with JavaScript. Screenshotly provides several mechanisms to ensure content is fully rendered before capturing.
Delay parameter
The delay parameter specifies how many milliseconds to wait after the page loads before taking the screenshot (0–10000):
const screenshot = await client.capture({
url: 'https://example.com',
delay: 3000 // wait 3 seconds
});
Use delay when:
- The page has animations that need to complete
- Content loads via JavaScript after the initial page load
- You need to wait for fonts or images to render
Wait for selector
The wait_for_selector parameter waits for a specific DOM element to appear before capturing:
const screenshot = await client.capture({
url: 'https://example.com/dashboard',
wait_for_selector: '.dashboard-loaded'
});
This is more reliable than a fixed delay because it captures as soon as the element exists, rather than waiting an arbitrary amount of time.
Element capture with selector
The selector parameter captures a specific element instead of the full page:
curl -X POST https://api.screenshotly.dev/v1/capture \
-H "X-API-Key: $SCREENSHOTLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"options": {
"selector": "#hero-section",
"selector_scroll_into_view": true
}
}' \
--output element.png
| Parameter | Type | Default | Description |
|---|
selector | string | — | CSS selector of the element to capture |
selector_scroll_into_view | boolean | true | Scroll the element into view before capturing |
error_on_selector_not_found | boolean | false | Return a 422 error if the selector is not found |
selector and wait_for_selector serve different purposes: selector captures a specific element, while wait_for_selector waits for an element to appear before capturing the full page (or viewport).
Navigation control with wait_until
The wait_until parameter controls when the page is considered loaded:
| Value | Description |
|---|
load (default) | Wait for the load event |
domcontentloaded | Wait for DOMContentLoaded event (faster) |
networkidle0 | Wait until no network connections for 500ms |
networkidle2 | Wait until 2 or fewer network connections for 500ms |
const screenshot = await client.capture({
url: 'https://example.com/spa',
wait_until: 'networkidle0' // wait for all network activity to finish
});
You can also pass an array to wait for multiple conditions:
{
"url": "https://example.com",
"options": {
"wait_until": ["load", "networkidle2"]
}
}
Combining options
You can use delay, wait_for_selector, and wait_until together. The API waits for navigation (wait_until), then for the selector (wait_for_selector), then applies the additional delay:
const screenshot = await client.capture({
url: 'https://example.com/charts',
wait_until: 'networkidle2',
wait_for_selector: '.chart-container',
delay: 1000 // extra second after element appears
});
When capturing SPAs built with React, Vue, or Angular, use wait_for_selector targeting a container that only renders after data loads. This is more reliable than guessing a delay value.
Timeouts
If the page takes too long to load or the selector never appears, the request will time out.
| Parameter | Default | Range | Description |
|---|
timeout | 60000 | 1000–90000 | Total timeout for the entire capture process |
navigation_timeout | 30000 | 1000–30000 | Timeout specifically for page navigation |
const screenshot = await client.capture({
url: 'https://slow-site.example.com',
wait_for_selector: '.content',
timeout: 90000, // 90 seconds total
navigation_timeout: 30000 // 30 seconds for page load
});
If the wait_for_selector element never appears on the page, the request will fail after the timeout period. Set error_on_selector_not_found: true to get a clear error, or ensure the selector matches an element that will exist.