ScreenshotNeo

BlogHow-to

How to Set Viewport Size and Device Scale Factor in Browserless Screenshots

Set the Browserless viewport and device scale factor through REST, BAP, or BrowserQL. Learn how CSS viewport dimensions differ from screenshot output pixels.

By the ScreenshotNeo team4 October 20267 min read

Set width, height, and deviceScaleFactor on the viewport configuration for the Browserless interface you use. In the REST Screenshot API, send a viewport object in the request. In Browserless BAP, call page.setViewport() before navigation when responsive layout matters. In BrowserQL, use the viewport mutation before the screenshot mutation.

Viewport width and height describe the page’s CSS-pixel viewing area and affect responsive layout. The device scale factor sets the browser’s device scaling context, associated with devicePixelRatio. Do not assume viewport dimensions alone guarantee a particular final screenshot raster size across every Browserless endpoint and capture configuration; verify the exact surface if output pixel dimensions are a hard requirement.

1. Choose the Browserless interface

Browserless exposes different request shapes for REST, BAP, and BrowserQL. Their similarly named viewport settings do not make their full configuration interchangeable.

Interface How to set the viewport Good fit
REST Screenshot API Include viewport in the JSON POST body A direct HTTP screenshot request
BAP Call page.setViewport() on the page A browser workflow with navigation, waits, or interactions
BrowserQL Run the viewport mutation A BrowserQL session with explicit browser operations

Check the documentation for the specific endpoint and deployment you use for supported fields, authentication, and request details.

2. Set viewport and scale with the REST Screenshot API

POST a JSON request to /screenshot. Keep page viewport settings separate from capture options such as image type, full-page capture, or clipping.

curl -X POST "https://production-sfo.browserless.io/screenshot?token=YOUR_BROWSERLESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "url": "https://example.com/",
    "viewport": {
      "width": 1280,
      "height": 720,
      "deviceScaleFactor": 2
    },
    "options": {
      "type": "png"
    }
  }' \
  --output screenshot.png

The host shown is an example Browserless endpoint pattern; use the endpoint and token for your account. The request sets a 1280-by-720 CSS-pixel viewport, a device scale factor of 2, and PNG capture output. Browserless documents PNG, JPEG, and WebP formats. Confirm the current REST reference for endpoint-specific fields and capture options.

Using Python

import requests

endpoint = "https://production-sfo.browserless.io/screenshot"
params = {"token": "YOUR_BROWSERLESS_TOKEN"}
payload = {
    "url": "https://example.com/",
    "viewport": {
        "width": 1280,
        "height": 720,
        "deviceScaleFactor": 2,
    },
    "options": {"type": "png"},
}

response = requests.post(
    endpoint,
    params=params,
    json=payload,
    timeout=90,
)
response.raise_for_status()
with open("screenshot.png", "wb") as image_file:
    image_file.write(response.content)

Using Node.js

const endpoint = new URL("https://production-sfo.browserless.io/screenshot");
endpoint.searchParams.set("token", "YOUR_BROWSERLESS_TOKEN");

const response = await fetch(endpoint, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    url: "https://example.com/",
    viewport: {
      width: 1280,
      height: 720,
      deviceScaleFactor: 2,
    },
    options: { type: "png" },
  }),
});

if (!response.ok) {
  throw new Error(`Screenshot request failed: ${response.status} ${await response.text()}`);
}

const image = Buffer.from(await response.arrayBuffer());
await import("node:fs/promises").then(({ writeFile }) => writeFile("screenshot.png", image));

3. Set the viewport in Browserless BAP

Set the viewport before navigating when you need the site to render its responsive layout at the intended width. Then navigate and capture:

await page.setViewport({
  width: 1280,
  height: 720,
  deviceScaleFactor: 2,
});

await page.goto("https://example.com/");
const image = await page.screenshot({ type: "png" });

Use the page and connection setup appropriate to your Browserless BAP environment. The important ordering for responsive pages is to establish the viewport before navigation and capture. BAP documents a default device scale factor of 1; specify a different value when you need another scaling context.

4. Set the viewport with BrowserQL

Use the BrowserQL viewport mutation to configure the session. The viewport mutation requires width and height; deviceScaleFactor defaults to 1.

mutation SetViewport {
  viewport(width: 1280, height: 720, deviceScaleFactor: 2) {
    width
    height
    deviceScaleFactor
  }
}

Run the screenshot mutation as a separate operation in the same BrowserQL workflow. BrowserQL also exposes mobile (default false), hasTouch (default false), and landscape (default false) on the viewport operation. Set those when the page needs those browser behaviors; changing width and height alone does not enable mobile emulation.

5. Understand viewport dimensions, scale, and output

  • Width and height: Define the CSS-pixel viewport and influence breakpoints, layout, and the visible area.
  • Device scale factor: Sets the device scaling context associated with devicePixelRatio. Browserless BAP and BrowserQL document a default of 1.
  • Capture options: Determine capture scope or output, such as full-page capture, selector, clipping, and image type. They do not set the responsive viewport.

Do not promise that a 1280-by-720 viewport at scale 2 will always produce a 2560-by-1440 output image. The reviewed Browserless references do not establish one output-pixel formula guaranteed across all endpoints, browser modes, and screenshot options. If downstream processing requires exact raster dimensions, inspect the returned image for the specific configuration and adjust or resize as needed.

6. Select capture options separately

Available fields vary by interface, so use that interface’s reference rather than copying option names blindly.

Need Relevant setting What it controls
Entire page fullPage Capture beyond the initial viewport where supported
One region or element clip or selector Limit capture to a rectangle or selected page element, where supported
Image format type Choose a supported format, such as PNG, JPEG, or WebP where offered
Image quality quality Set lossy image quality where supported; BrowserQL documents that it does not apply to PNG
Transparent page background omitBackground Omit the default background where supported
Wait for images waitForImages Wait for image loading where supported

BrowserQL documents fullPage as false by default. It also documents captureBeyondViewport as false when no clip is present and true otherwise. For long pages with lazy-loaded content, the REST guide describes scrollPage: true to scroll before capture and trigger lazy loading; use it with full-page capture when a complete page is wanted. Check the relevant reference for the precise syntax.

7. Troubleshoot common results

Symptom Likely cause What to check
Page uses the wrong responsive layout The viewport was set after navigation, omitted, or sent in a field shape unsupported by that interface Set it before navigation in BAP; validate the REST request or BrowserQL mutation against its own reference.
Screenshot has unexpected raster dimensions CSS viewport dimensions and final output pixels are being treated as the same measurement Inspect the returned image from the exact endpoint and capture configuration; resize explicitly if exact dimensions are required.
Mobile layout does not appear A narrow viewport was set without enabling mobile-related emulation behavior For BrowserQL, review the separate mobile, hasTouch, and landscape settings. Confirm the equivalent controls for other interfaces.
Images or lower-page content are missing Images had not loaded or lazy content was not triggered before capture Use the surface’s image-wait option where available; for REST long-page captures, review scrollPage with full-page capture.
Screenshot differs from a normal visit The target may block automation or show a bot check Inspect the rendered page and Browserless troubleshooting guidance; a bot check can prevent the expected page from rendering.
Request fails or returns an error Token, endpoint, JSON, or supported option may be wrong Check the response status and body, verify the token and endpoint, and compare the payload with the current endpoint-specific documentation.

8. Reliability, performance, and cost considerations

Viewport size can change which assets and responsive components a page loads, so use the dimensions that match the intended rendering context. Larger or full-page captures can involve more page content; wait only for the resources and readiness conditions the task needs. Pages with lazy loading may require scrolling before capture. Keep viewport setup, navigation readiness, and screenshot options explicit so a changed result can be traced to the right setting.

The research references do not provide a universal Browserless cost formula, performance benchmark, or guarantee for screenshot output dimensions. Check the current Browserless plan and endpoint documentation for account-specific limits and pricing. For exact-size downstream assets, validate dimensions rather than deriving them from viewport and scale alone.

9. Or skip the browser setup

ScreenshotNeo takes a screenshot with one GET request. The URL below uses the same example page; see the ScreenshotNeo API documentation for its options and response behavior.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

Equivalent Python request:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Equivalent Node.js request:

const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://example.com',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(({ writeFile }) => writeFile('shot.webp', image));

ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots, and 1,000 screenshots per month are free with no card; paid plans start at $5 for 3,000. Sign up for the free plan.

10. FAQ

What device scale factor should I use?

Use 1 for the documented default in BAP and BrowserQL. Choose another value when your capture needs a different device scaling context, and verify the resulting image on the specific endpoint.

Does device scale factor change the responsive breakpoint?

Responsive layout is driven by the CSS-pixel viewport width. Device scale factor describes device scaling; it is not a substitute for setting the intended viewport width.

Does a viewport of 1280 by 720 mean the image will be 1280 by 720 pixels?

Not necessarily. Those are viewport dimensions in CSS pixels. The final raster dimensions depend on the endpoint and capture configuration, so inspect the output when exact dimensions matter.

Can I use the same JSON for REST, BAP, and BrowserQL?

No. REST takes an HTTP request body, BAP uses page methods, and BrowserQL uses mutations. Follow the documentation for the surface you selected.

References