# Multi-Resolution Screenshot Tool — Mobile to Desktop (`junipr/multi-resolution-screenshot`) Actor

Capture mobile, tablet, desktop, and custom viewport screenshots of webpages with selectors, waiting controls, KVS files, and dataset metadata.

- **URL**: https://apify.com/junipr/multi-resolution-screenshot.md
- **Developed by:** [junipr](https://apify.com/junipr) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 3 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $9.80 / 1,000 screenshot takens

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## Multi-Resolution Screenshot Tool — Mobile to Desktop

Capture mobile, tablet, desktop, and custom viewport screenshots of webpages with selectors, waiting controls, KVS files, and dataset metadata. Take screenshots at multiple viewport sizes in a single run with built-in device presets, full-page capture, PNG/JPEG/WebP output, cookie banner dismissal, and element-specific screenshots.

Perfect for responsive design QA, visual regression testing, multi-device previews, SEO audits, and client reporting.

### Why Use This Actor

Unlike single-viewport screenshot tools that require separate runs for each device size, this actor captures all viewport variations in one run — saving time, compute costs, and workflow complexity.

| Feature | This Actor | Other Screenshot Actors |
|---------|-----------|------------------------|
| Multi-resolution per run | Yes (unlimited) | No (1 per run) |
| Device presets | 8 built-in | None |
| Full-page capture | Yes | Partial |
| WebP output | Yes | No |
| Cookie banner dismissal | Auto-detect | No |
| Element screenshots | Yes (clipSelector) | No |
| Structured file naming | Yes (customizable) | Random IDs |

### How to Use

**Zero-config (desktop screenshot of crawlee.dev):**

No input needed — runs with defaults.

**Multi-resolution responsive QA:**

```json
{
  "urls": [
    { "url": "https://example.com/", "label": "homepage" },
    { "url": "https://example.com/about", "label": "about" }
  ],
  "presets": ["mobile", "tablet", "desktop"],
  "fullPage": true
}
```

**Custom viewport dimensions:**

```json
{
  "urls": [{ "url": "https://example.com/", "label": "og-image" }],
  "viewports": [{ "width": 1200, "height": 630, "label": "og" }],
  "format": "jpeg",
  "quality": 90
}
```

Screenshots are saved to the Key-Value Store. Retrieve them via the Apify API or download from the Console.

### Input Configuration

| Parameter | Default | Description |
|-----------|---------|-------------|
| `urls` | crawlee.dev | Array of `{ url, label }` objects. Max 100. |
| `presets` | `["desktop"]` | Device presets: mobile, tablet, desktop, desktopHd, 4k, ultrawide |
| `fullPage` | `false` | Capture full scrollable page |
| `format` | `png` | Output: png, jpeg, or webp |
| `quality` | `80` | JPEG/WebP quality (1-100) |
| `clipSelector` | — | Screenshot only this CSS element |
| `hideSelectors` | `[]` | Hide elements before capture |
| `dismissCookieBanners` | `true` | Auto-dismiss cookie consent |
| `waitForSelector` | — | Wait for element before capture |
| `waitForTimeout` | `1000` | Wait ms after page load |
| `fileNamePattern` | `{label}_{preset}_{width}x{height}` | KV store key pattern |

### Output Format

Each screenshot produces a dataset item:

```json
{
  "url": "https://example.com/",
  "label": "homepage",
  "viewport": {
    "width": 375,
    "height": 812,
    "deviceScaleFactor": 2,
    "isMobile": true,
    "preset": "mobile"
  },
  "screenshot": {
    "kvStoreKey": "homepage_mobile_375x812.png",
    "kvStoreUrl": "https://api.apify.com/v2/key-value-stores/.../records/homepage_mobile_375x812.png",
    "format": "png",
    "width": 750,
    "height": 1624,
    "fileSizeBytes": 245760,
    "fileSizeHuman": "240.0 KB"
  },
  "page": {
    "title": "Example Domain",
    "statusCode": 200,
    "fullPageHeight": 812,
    "loadTimeMs": 1234
  },
  "capturedAt": "2025-01-15T10:30:00.000Z",
  "errors": []
}
```

A `RUN_SUMMARY` JSON is saved to the KV store with totals, durations, and per-screenshot status.

### Tips and Advanced Usage

- **Cookie banners:** Enabled by default. Auto-detects OneTrust, CookieBot, Quantcast, and generic consent banners.
- **Authenticated pages:** Pass session cookies via the `cookies` input for pages behind login.
- **Custom JS:** Use `javascript` to modify the page before capture (e.g., change theme, remove elements).
- **Performance:** Set `blockResources: ["image", "font"]` for faster captures when full rendering isn't needed.
- **Element screenshots:** Use `clipSelector: "#hero"` to capture just one component.
- **Lazy loading:** `scrollToBottom` (default: false) triggers intersection observers for lazy images when enabled.

### Pricing

Pay-per-event pricing with the `screenshot-taken` event: **$0.0098 per screenshot** ($9.80 per 1,000) in the queued monetization update.

One screenshot = one URL at one viewport. Examples:

- 1 URL x 1 viewport = 1 screenshot = $0.0098
- 10 URLs x 3 viewports = 30 screenshots = $0.29
- 100 URLs x 8 viewports = 800 screenshots = $7.84

Platform usage pass-through is queued because each screenshot can consume browser, proxy, storage, and bandwidth resources. Failed screenshots (navigation errors, timeouts) are not charged.

### FAQ

#### What viewport sizes are supported?

8 built-in presets: mobile (375x812), mobileLandscape (812x375), tablet (768x1024), tabletLandscape (1024x768), desktop (1280x800), desktopHd (1920x1080), 4k (3840x2160), ultrawide (2560x1080). Custom dimensions also supported.

#### Can I capture full-page screenshots?

Yes. Set `fullPage: true` to capture the entire scrollable page. Lazy-loaded images are triggered by auto-scrolling before capture.

#### How do I handle cookie consent banners?

Enabled by default via `dismissCookieBanners: true`. Supports major consent managers. Use `hideSelectors` or `clickSelectors` for custom banners.

#### Can I screenshot pages that require login?

Yes. Pass session cookies via the `cookies` input or set auth headers via `httpHeaders`.

#### What's the maximum number of URLs per run?

100 URLs per run with up to 20 viewports each.

#### What output formats are supported?

PNG (default, lossless), JPEG (lossy, smaller files), and WebP (modern, best compression). Quality configurable for JPEG/WebP.

#### How are screenshots named in the Key-Value Store?

Following the `fileNamePattern` template. Default: `{label}_{preset}_{width}x{height}.{format}`. Example: `homepage_mobile_375x812.png`.

#### How is a "screenshot" defined for pricing?

One URL captured at one viewport = one billable screenshot. Multiple viewports of the same URL count as multiple screenshots.

# Actor input Schema

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

URLs to capture. Each entry: { "url": "https://.../", "label": "optional-name" }. Label is used in file naming.

## `presets` (type: `array`):

Named viewport presets: mobile (375x812), tablet (768x1024), desktop (1280x800), desktopHd (1920x1080), 4k (3840x2160), ultrawide (2560x1080).

## `fullPage` (type: `boolean`):

Capture the full scrollable page, not just the viewport.

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

Output format for screenshots.

## `quality` (type: `integer`):

JPEG/WebP quality (1-100). Ignored for PNG.

## `omitBackground` (type: `boolean`):

Make background transparent (PNG/WebP only).

## `clipSelector` (type: `string`):

CSS selector — screenshot only this element's bounding box.

## `hideSelectors` (type: `array`):

CSS selectors for elements to hide before capture (e.g., cookie banners, modals).

## `clickSelectors` (type: `array`):

CSS selectors to click before screenshot (e.g., dismiss popups). Executed in order.

## `waitForSelector` (type: `string`):

Wait for this CSS selector to appear before capturing.

## `waitForTimeout` (type: `integer`):

Wait N ms after page load before capturing.

## `waitForNetworkIdle` (type: `boolean`):

Wait until no network requests for 500ms.

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

Scroll page to bottom before capture to trigger lazy-loaded images.

## `dismissCookieBanners` (type: `boolean`):

Auto-detect and dismiss cookie consent banners.

## `javascript` (type: `string`):

JavaScript to execute before capture. Max 10,000 chars.

## `fileNamePattern` (type: `string`):

KV store key pattern. Tokens: {url}, {domain}, {label}, {preset}, {width}, {height}, {scale}, {format}, {timestamp}.

## `maxConcurrency` (type: `integer`):

Maximum concurrent browser pages.

## `maxRetries` (type: `integer`):

Retry failed screenshots up to N times.

## `requestTimeout` (type: `integer`):

Timeout per page load in milliseconds.

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

Proxy settings. Defaults to Apify datacenter proxies.

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://crawlee.dev/",
      "label": "crawlee"
    }
  ],
  "presets": [
    "desktop"
  ],
  "fullPage": false,
  "format": "png",
  "quality": 80,
  "omitBackground": false,
  "clipSelector": "",
  "hideSelectors": [],
  "clickSelectors": [],
  "waitForSelector": "",
  "waitForTimeout": 1000,
  "waitForNetworkIdle": true,
  "scrollToBottom": false,
  "dismissCookieBanners": true,
  "javascript": "",
  "fileNamePattern": "{label}_{preset}_{width}x{height}",
  "maxConcurrency": 1,
  "maxRetries": 1,
  "requestTimeout": 30000,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Screenshot metadata including viewport, file size, page title, and KV store URLs for each captured image.

# 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://crawlee.dev/",
            "label": "crawlee"
        }
    ],
    "presets": [
        "desktop"
    ],
    "format": "png",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("junipr/multi-resolution-screenshot").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://crawlee.dev/",
            "label": "crawlee",
        }],
    "presets": ["desktop"],
    "format": "png",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("junipr/multi-resolution-screenshot").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://crawlee.dev/",
      "label": "crawlee"
    }
  ],
  "presets": [
    "desktop"
  ],
  "format": "png",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call junipr/multi-resolution-screenshot --silent --output-dataset

```

## MCP server setup

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

```

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/3G3YvvNwIXFREsTO7/builds/zh0fkWmJ1WKKEyfv7/openapi.json
