# Website Screenshot Generator (`crawlerbros/screenshot-url`) Actor

Capture full-page screenshots of any website as PNG images or PDF documents. Supports custom viewport, scroll-to-bottom, element hiding, and configurable wait conditions.

- **URL**: https://apify.com/crawlerbros/screenshot-url.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Other, SEO tools, Developer tools
- **Stats:** 246 total users, 24 monthly users, 93.4% runs succeeded, 4 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Screenshot URL

Capture full-page screenshots of any website as PNG images or PDF documents. Supports custom viewport sizes, scroll-to-bottom for lazy-loaded content, element hiding, and configurable wait conditions.

### What can this actor do?

- **Full-page screenshots** -- Capture entire web pages as PNG images or PDF documents
- **Custom viewport** -- Set browser width from 100px to 3840px to test responsive layouts
- **Scroll to bottom** -- Trigger lazy-loaded images and infinite scroll content before capturing
- **Hide elements** -- Remove cookie banners, popups, and ads using CSS selectors
- **Wait conditions** -- Wait for page load, DOM ready, or network idle before capturing
- **Custom delay** -- Add delay after page load for animations or dynamic content
- **Redirect tracking** -- Records the final URL after any redirects
- **Bulk capture** -- Process multiple URLs in a single run
- **PDF export** -- Generate printable PDF documents from web pages

### Use cases

- **Website monitoring** -- Schedule regular screenshots to track visual changes over time
- **Quality assurance** -- Verify website appearance across different viewport widths
- **Archiving** -- Save snapshots of web pages for records or compliance
- **Competitive analysis** -- Capture competitor websites for design comparison
- **Bug reporting** -- Generate visual evidence of display issues
- **Content verification** -- Confirm that published content appears correctly

### Input

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `urls` | URL\[] | Yes | -- | Web page URLs to screenshot |
| `format` | string | No | `png` | Output format: `png` or `pdf` |
| `waitUntil` | string | No | `load` | Page load event: `load`, `domcontentloaded`, or `networkidle` |
| `delay` | integer | No | 0 | Delay before screenshot in milliseconds (0--3,600,000) |
| `viewportWidth` | integer | No | 1280 | Browser viewport width in pixels (100--3,840) |
| `scrollToBottom` | boolean | No | false | Scroll to bottom before screenshot |
| `delayAfterScrolling` | integer | No | 2500 | Delay after scrolling in milliseconds (0--3,600,000) |
| `waitUntilNetworkIdleAfterScroll` | boolean | No | false | Wait for network idle after scrolling |
| `waitUntilNetworkIdleAfterScrollTimeout` | integer | No | 30000 | Network idle timeout in milliseconds (1,000--3,600,000) |
| `proxyConfiguration` | object | No | -- | Proxy settings (optional) |
| `selectorsToHide` | string | No | -- | CSS selectors to hide before screenshot (comma-separated) |

#### Example input

```json
{
    "urls": [
        {"url": "https://www.example.com/"},
        {"url": "https://news.ycombinator.com/"}
    ],
    "format": "png",
    "waitUntil": "networkidle",
    "viewportWidth": 1920
}
```

```json
{
    "urls": [
        {"url": "https://www.wikipedia.org/"}
    ],
    "format": "pdf",
    "scrollToBottom": true,
    "selectorsToHide": ".cookie-banner, #popup"
}
```

### Output

Each URL produces one row in the dataset with a link to the screenshot file stored in the key-value store.

| Field | Type | Description |
|-------|------|-------------|
| `startUrl` | string | The original URL provided as input |
| `url` | string | The final URL after any redirects |
| `screenshotUrl` | string | Public URL to download the screenshot file |
| `screenshotKey` | string | Key name in the key-value store |
| `format` | string | Screenshot format (`png` or `pdf`) |
| `status` | string | `success` or error description |
| `timestamp` | string | ISO 8601 timestamp |

#### Sample output

```json
{
    "startUrl": "https://www.example.com/",
    "url": "https://www.example.com/",
    "screenshotUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/screenshot_https___www_example_com__abc123.png",
    "screenshotKey": "screenshot_https___www_example_com__abc123.png",
    "format": "png",
    "status": "success",
    "timestamp": "2026-03-23T12:00:00.000000+00:00"
}
```

### How it works

1. Launches a Chromium browser with the configured viewport width
2. Navigates to each URL and waits for the specified load condition
3. Optionally scrolls to the bottom to trigger lazy-loaded content
4. Optionally hides specified elements (cookie banners, popups, ads)
5. Captures a full-page screenshot as PNG or generates a PDF document
6. Stores the screenshot file in the key-value store with a public download URL
7. Records the result in the dataset with the original URL, final URL, and screenshot link

### Tips for best results

- Use `networkidle` for `waitUntil` on pages with heavy JavaScript rendering
- Enable `scrollToBottom` for pages with lazy-loaded images or infinite scroll
- Use `selectorsToHide` to remove cookie consent banners and popups: `.cookie-banner, #consent-popup, .ad-wrapper`
- Set a `delay` of 1000-3000ms for pages with entrance animations
- Use wider `viewportWidth` (1920) for desktop-optimized pages, or 375 for mobile views
- The actor works without proxy for most websites; enable proxy only if needed

### Limitations

- Some websites may block screenshots from datacenter IPs. Use proxy configuration for these sites
- Very long pages may produce large PNG files. Consider using PDF format for document-heavy pages
- JavaScript-heavy single-page applications may need `networkidle` wait condition and additional delay
- The actor cannot log into websites or handle authentication
- PDF format uses the browser's print layout, which may differ from the visual page appearance

### Frequently Asked Questions

**Do I need a proxy?**
No. The actor works without proxy for most publicly accessible websites. Only enable proxy if the target site blocks datacenter IPs.

**What is the difference between PNG and PDF?**
PNG captures a full-page screenshot as an image, including everything visible when scrolled. PDF generates a printable document using the browser's print functionality, which may paginate content differently.

**How do I hide cookie banners?**
Use the `selectorsToHide` field with CSS selectors. For example: `.cookie-banner, #gdpr-consent, [class*="cookie"]`.

**What viewport height is used?**
The viewport height is fixed at 1080px. The screenshot captures the full page length regardless of viewport height.

**How does scroll-to-bottom work?**
The actor scrolls the page in 250px increments, triggering lazy-loaded images and content. After scrolling, it waits for the configured delay or network idle before taking the screenshot.

**Can I screenshot multiple pages in one run?**
Yes. Add multiple URLs to the input. Each URL produces a separate screenshot and dataset row.

**Where are the screenshot files stored?**
Screenshots are stored in the run's key-value store. Each dataset row includes a `screenshotUrl` field with a direct download link.

**Can I take mobile screenshots?**
Yes. Set `viewportWidth` to a mobile width like 375 or 390 to simulate a mobile browser viewport.

# Actor input Schema

## `urls` (type: `array`):

List of web page URLs to capture as screenshots.

## `format` (type: `string`):

Screenshot output format. PNG captures a full-page image. PDF generates a printable document.

## `waitUntil` (type: `string`):

When to consider the page loaded before taking the screenshot.

## `delay` (type: `integer`):

Milliseconds to wait after the page loads before taking the screenshot. Useful for pages with animations or lazy-loaded content.

## `viewportWidth` (type: `integer`):

Browser viewport width in pixels. Height is fixed at 1080px.

## `scrollToBottom` (type: `boolean`):

Scroll to the bottom of the page before taking the screenshot. Triggers lazy-loaded images and infinite scroll content.

## `delayAfterScrolling` (type: `integer`):

Milliseconds to wait after scrolling to bottom. Only applies when Scroll to Bottom is enabled and Wait for Network Idle After Scroll is disabled.

## `waitUntilNetworkIdleAfterScroll` (type: `boolean`):

After scrolling, wait until no network requests are made for 500ms. Ensures all lazy-loaded content finishes loading. Overrides Delay After Scrolling.

## `waitUntilNetworkIdleAfterScrollTimeout` (type: `integer`):

Maximum time to wait for network idle after scrolling. Only applies when Wait for Network Idle After Scroll is enabled.

## `proxyConfiguration` (type: `object`):

Optional proxy settings. The actor works without proxy for most websites.

## `selectorsToHide` (type: `string`):

Comma-separated CSS selectors of elements to hide before taking the screenshot. Example: '.cookie-banner, #popup, .ads'

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://www.apify.com/"
    }
  ],
  "format": "png",
  "waitUntil": "load",
  "delay": 0,
  "viewportWidth": 1280,
  "scrollToBottom": false,
  "delayAfterScrolling": 2500,
  "waitUntilNetworkIdleAfterScroll": false,
  "waitUntilNetworkIdleAfterScrollTimeout": 30000
}
```

# Actor output Schema

## `screenshots` (type: `string`):

Dataset containing results for each screenshotted URL

## `screenshotFiles` (type: `string`):

Key-value store containing the screenshot PNG/PDF files

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        {
            "url": "https://www.apify.com/"
        }
    ],
    "waitUntil": "load",
    "delay": 0,
    "viewportWidth": 1280
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/screenshot-url").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "urls": [{ "url": "https://www.apify.com/" }],
    "waitUntil": "load",
    "delay": 0,
    "viewportWidth": 1280,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/screenshot-url").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    {
      "url": "https://www.apify.com/"
    }
  ],
  "waitUntil": "load",
  "delay": 0,
  "viewportWidth": 1280
}' |
apify call crawlerbros/screenshot-url --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawlerbros/screenshot-url"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/qrOE8NXzFv7QBVzsX/builds/gFtOgl6UEbKrZi7hu/openapi.json
