ScreenshotNeo

BlogHow-to

How to Set the Viewport Size for a Playwright Full-Page Screenshot

Set a predictable Playwright viewport before navigation, then use fullPage: true to capture the entire scrollable page.

By the ScreenshotNeo team4 October 20267 min read

Set the viewport before navigating, then pass fullPage: true to page.screenshot(). The viewport controls the page’s layout dimensions in CSS pixels; fullPage controls how much of the document the screenshot includes.

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext();
  const page = await context.newPage();

  await page.setViewportSize({ width: 1280, height: 800 });
  await page.goto('https://example.com', { waitUntil: 'load' });
  await page.screenshot({ path: 'screenshot.png', fullPage: true });

  await browser.close();
})();

Install Playwright with npm install playwright. If you use the Playwright Test runner, install and configure @playwright/test instead. The examples below use the official Page API and screenshot guidance.

1. Understand viewport size and full-page capture

A viewport is the browser page’s layout area, measured in CSS pixels. For example, a viewport of 1280 by 800 asks the page to lay itself out as if it had 1280 CSS pixels of width and 800 CSS pixels of height. Responsive breakpoints, column widths, and other layout decisions can depend on these dimensions.

fullPage: true captures the full scrollable document, including content below the viewport. It does not choose the layout width. Keep the two settings separate: set the viewport to control the page layout, and set fullPage to control capture extent. The screenshot option defaults to false, which captures only the currently visible viewport.

Setting Controls Example
viewport or setViewportSize() Page layout dimensions { width: 1280, height: 800 }
fullPage Whether to include the full scrollable page true
scale Output pixels per CSS pixel 'css' or 'device'

2. Set a viewport for one page

Call page.setViewportSize() before page.goto() whenever possible. Some websites do not respond as expected if phone-sized dimensions are applied after the page loads. Changing the viewport also resets the page’s screen size.

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext();
  const page = await context.newPage();

  await page.setViewportSize({ width: 390, height: 844 });
  await page.goto('https://example.com');
  await page.screenshot({
    path: 'mobile-full-page.png',
    fullPage: true,
  });

  await browser.close();
})();

Use positive integer pixel dimensions. Pick the width that represents the layout you want to render. The height sets the initial viewport height and can affect viewport-dependent behavior, but fullPage: true extends the capture to the document’s full scrollable height.

Set viewport and screen together

If you need explicit control of both the viewport and the page’s screen dimensions, create a context with both options:

const context = await browser.newContext({
  viewport: { width: 1280, height: 800 },
  screen: { width: 1280, height: 800 },
});
const page = await context.newPage();
await page.goto('https://example.com');
await page.screenshot({ path: 'full.png', fullPage: true });

3. Configure a shared viewport in Playwright Test

Set use.viewport in the Playwright Test configuration when a project should use the same viewport for its pages. The documented default is 1280 by 720 pixels; spelling it out makes the intended dimensions visible in the project configuration.

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    viewport: { width: 1280, height: 800 },
  },
});

Then capture a full page in a test:

import { test } from '@playwright/test';

test('captures the full page', async ({ page }) => {
  await page.goto('https://example.com');
  await page.screenshot({ path: 'artifacts/example.png', fullPage: true });
});

A project-wide viewport is useful for consistency across tests. Use page.setViewportSize() when a particular test needs different dimensions. Setting the configured viewport to null makes it depend on the host window size, so runs may be non-deterministic across machines.

4. Choose full-page and output-scale options

Full page versus viewport only

// Only what is currently visible in the viewport (the default)
await page.screenshot({ path: 'viewport.png' });

// The full scrollable document
await page.screenshot({ path: 'full-page.png', fullPage: true });

CSS pixels versus device pixels

scale: 'css' produces one output image pixel per CSS pixel. This can keep high-DPI screenshots smaller. scale: 'device' uses device-pixel resolution and is the documented default; use it when device-pixel detail matters.

await page.screenshot({
  path: 'full-page-css-scale.png',
  fullPage: true,
  scale: 'css',
});

Choose the scale based on the consumer of the image. A CSS-scale image has dimensions closer to the page’s CSS dimensions; device scale can produce more output pixels and a larger file.

Output format and stable captures

Playwright infers the image type from the file extension when saving to a path. Screenshot output supports PNG, JPEG, and WebP. You can also specify type explicitly:

await page.screenshot({
  path: 'full-page.webp',
  type: 'webp',
  fullPage: true,
});

For repeatable screenshots, screenshot options also include animation handling and an injected stylesheet. Disabling animations fast-forwards finite animations and cancels infinite ones, according to the API documentation. An injected stylesheet can hide or normalize elements that make visual comparisons unstable.

await page.screenshot({
  path: 'stable.png',
  fullPage: true,
  animations: 'disabled',
  style: '.timestamp, .random-banner { visibility: hidden !important; }',
});

5. Complete runnable example with a full-page screenshot

This standalone Node.js script creates a browser and context, sets the viewport before navigation, waits for the page load event, and writes a full-page PNG. Save it as screenshot.js and run node screenshot.js after installing Playwright and its browser.

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  try {
    const context = await browser.newContext({
      viewport: { width: 1280, height: 800 },
    });
    const page = await context.newPage();

    await page.goto('https://example.com', { waitUntil: 'load' });
    await page.screenshot({
      path: 'example-full-page.png',
      fullPage: true,
      scale: 'css',
      animations: 'disabled',
    });
  } finally {
    await browser.close();
  }
})();

To capture a different responsive layout, change the context’s viewport width and height. To retain device-pixel output, remove scale: 'css' or set it to 'device'.

6. Capture with the Playwright CLI code generator

If you are using Playwright’s code generator, the documented --viewport-size option accepts dimensions in width,height form. For example:

npx playwright codegen --viewport-size="800,600" https://example.com

This controls the generated browser’s viewport while you record interactions. For a script that takes the screenshot, still set the page or context viewport and pass fullPage: true to the screenshot call.

7. Common problems and fixes

Symptom Likely cause Fix
Image is only the visible screen fullPage was omitted or is false Pass fullPage: true to page.screenshot().
Page layout has the wrong width The viewport was set after navigation, or the chosen width triggers a different responsive breakpoint Set the dimensions before goto(); choose the intended CSS-pixel width.
Screenshot dimensions look larger than expected scale: 'device' uses device pixels Use scale: 'css' for one image pixel per CSS pixel.
Screenshot size changes across machines The viewport depends on the host window, such as when configured as null Set explicit width and height in the context or test configuration.
Page or test uses a different screen size than expected setViewportSize() also resets the page’s screen size Configure both screen and viewport on browser.newContext() when both need explicit values.
Full-page capture is slow or produces a large file The document is very tall, the scale is device pixels, or the selected format is large for the content Use CSS scale when appropriate, select a suitable supported format, and capture only the pages and dimensions the workflow needs.
Screenshot contains moving or changing elements Animations, timestamps, or dynamic content changed during capture Disable animations and use an injected stylesheet for known visual noise. For dynamic page content, wait for the relevant content to become ready before capturing.

8. Performance, reliability, and cost considerations

  • Keep dimensions explicit. Fixed viewport settings make layout and screenshot output more reproducible across local and CI environments.
  • Choose an appropriate scale. CSS scale can reduce output pixel dimensions on high-DPI captures; device scale retains device-pixel detail and may increase image size.
  • Account for page height. Full-page output includes the entire scrollable document, so very long pages naturally require more image data than viewport-only captures.
  • Wait for the content your screenshot needs. The load event is a useful baseline, but applications may render or fetch important content later. Wait for a meaningful selector or app-specific ready state when needed.
  • Close the browser reliably. Use try/finally so a failed navigation or capture does not leave the browser process running.
  • Plan for local browser resources. Rendering pages consumes machine time and memory; reuse a browser across a batch of captures when appropriate, while creating an isolated context when you need separate viewport or browser state.

Playwright is a browser automation library, so its direct cost depends on the environment where you run it, including compute and storage. The cited Playwright documentation does not specify a per-screenshot service price.

9. Or skip the browser setup

ScreenshotNeo provides a website screenshot API: one GET request returns an image or PDF. Set the viewport dimensions with viewport_width and viewport_height; use full_page=true for a full-page capture. See the ScreenshotNeo API documentation for parameters and response details.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://example.com \
  -d viewport_width=1280 \
  -d viewport_height=800 \
  -d full_page=true \
  -o screenshot.png

Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers say which page verdict and billing outcome applied. An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.

Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card.

10. FAQ

Does the viewport height limit a full-page screenshot?

No. The viewport height sets the layout viewport. With fullPage: true, Playwright captures the page’s full scrollable document.

Should I set the viewport before or after navigation?

Before navigation is the safer default, especially when the target uses responsive layouts.

What dimensions should I use?

Use the CSS-pixel width and height that match the layout you want to capture. There is no single correct size for every site; the width can change responsive behavior.

How do I make output dimensions correspond to CSS pixels?

Set scale: 'css'. The default device scale uses device pixels instead.

Can I use full-page capture in Playwright Test?

Yes. Configure the project viewport with use.viewport, then call page.screenshot({ fullPage: true }) in the test.