ScreenshotNeo

BlogHow-to

Playwright Screenshot Cuts Off the Right Side of a Wide Web Page: Fixes

Find why a Playwright screenshot misses the right side, compare viewport and document widths, and choose the right fix for full-page, clipped, or high-resolution captures.

By the ScreenshotNeo team4 October 20267 min read

Direct answer: Playwright’s fullPage: true captures the page’s full scrollable height; it does not widen the browser viewport. If the screenshot cuts off content on the right, compare the page’s CSS viewport width with its document width, then either set the intended viewport before the page lays out or capture the specific region you need. Increasing screenshot pixel scale changes output resolution, not the page’s CSS layout.

1. Identify what the screenshot should contain

First decide which of these you need:

Goal Playwright setting What it captures
What is currently visible Default screenshot The page’s current viewport
The whole vertical page fullPage: true The full scrollable page height, at the current layout width
A desktop layout wider than the default viewport Set a wider viewport before navigation or layout The page rendered at that CSS viewport width
A known portion of the page clip: { x, y, width, height } The specified rectangle, if the content is rendered there

A full-page screenshot can still be narrow: full-page refers to vertical scroll extent, not an instruction to reveal horizontally overflowing content. Playwright documents the screenshot options, including fullPage, clip geometry, and image scale.

2. Check viewport width against document width

Log the viewport and document dimensions in the same page state where the screenshot is taken. A document width larger than the viewport suggests horizontal overflow. Find the element responsible before changing CSS or selecting a wider viewport; the wider element might be intentional, such as a data table.

const dimensions = await page.evaluate(() => ({
  innerWidth: window.innerWidth,
  documentWidth: document.documentElement.scrollWidth,
  bodyWidth: document.body.scrollWidth,
}));
console.log(dimensions);

This comparison is a diagnostic technique, not a guarantee about the cause. Inspect the overflowing component, its parent containers, and any fixed-width or viewport-relative styles. Avoid applying overflow: hidden as a shortcut if the missing content must appear in the screenshot; that can conceal the symptom while discarding the content.

3. Set the intended CSS viewport before capture

For a wide desktop layout, create a context or page with the desired viewport before navigating. Choose the width that reflects the layout you want, rather than inferring it from a high-resolution output image.

JavaScript: complete runnable example

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

(async () => {
  const browser = await chromium.launch({ headless: true });
  const page = await browser.newPage({
    viewport: { width: 1600, height: 1000 },
  });

  try {
    await page.goto('https://example.com', { waitUntil: 'load' });
    const dimensions = await page.evaluate(() => ({
      innerWidth: window.innerWidth,
      documentWidth: document.documentElement.scrollWidth,
      bodyWidth: document.body.scrollWidth,
    }));
    console.log(dimensions);
    await page.screenshot({
      path: 'wide-page.png',
      fullPage: true,
      scale: 'css',
    });
  } finally {
    await browser.close();
  }
})();

Install Playwright and its Chromium browser according to the official setup guide. Replace the example URL and viewport dimensions with your target and intended layout. The context’s viewport determines the CSS width used for layout; set it before navigation when the site responds to viewport breakpoints.

Python: complete runnable example

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page(viewport={"width": 1600, "height": 1000})
    try:
        page.goto("https://example.com", wait_until="load")
        dimensions = page.evaluate("""() => ({
          innerWidth: window.innerWidth,
          documentWidth: document.documentElement.scrollWidth,
          bodyWidth: document.body.scrollWidth,
        })""")
        print(dimensions)
        page.screenshot(path="wide-page.png", full_page=True, scale="css")
    finally:
        browser.close()

cURL and Node.js notes

cURL does not control a local Playwright browser viewport. It is useful for calling a screenshot service that performs the browser capture remotely; see the alternative below. The JavaScript example above is runnable with Node.js and Playwright. Playwright’s Python API is shown separately because the title’s browser setup can also be used from Python.

4. Use clip only when a rectangle is the goal

A clip rectangle specifies x, y, width, and height. Ensure its right edge, x + width, reaches the content you intend to preserve. Clipping selects output coordinates; it does not force a responsive page to render a wider desktop layout or make off-viewport content exist.

await page.screenshot({
  path: 'selected-region.png',
  clip: { x: 0, y: 0, width: 1800, height: 1200 },
});

Use this when you know the exact region to capture. If the target is a responsive desktop layout, set the viewport first and verify the resulting layout instead of relying on a clip rectangle alone.

5. Choose output scale independently

Playwright’s scale: 'css' produces one image pixel per CSS pixel; scale: 'device' produces one image pixel per device pixel. These settings control raster density. They do not increase the CSS viewport width or fix a layout that has already rendered too narrowly.

// Compact output: one image pixel per CSS pixel
await page.screenshot({ path: 'page-css.png', fullPage: true, scale: 'css' });

// Device-pixel output: higher raster density on a high-DPI context
await page.screenshot({ path: 'page-device.png', fullPage: true, scale: 'device' });

Higher pixel density can create a larger image and use more memory. Select it when output detail needs it; do not use it as a substitute for a suitable viewport.

6. Troubleshooting common causes

Symptom Likely cause What to do
Right side is absent even with fullPage: true The page is laid out at a narrower viewport; fullPage concerns vertical extent. Log innerWidth and scrollWidth; set the intended viewport before navigation.
Document width is greater than viewport width An element or layout rule overflows horizontally. Inspect the wide element and decide whether it is intentional. If it is, capture the needed width; if not, correct the layout rule.
Image has more pixels but the same content cutoff Device-pixel scale changed raster resolution, not CSS layout width. Change the viewport width and verify layout, then choose output scale separately.
Clip output ends before the target The clip rectangle’s right boundary is too small or target content is outside the rendered area. Check x + width; render at the intended viewport before clipping.
Layout changes only in full-page output Viewport-relative CSS such as vh or vw may interact with full-page capture. Reduce the case to a small reproduction and compare viewport and full-page captures in the installed browser version. A historical Chromium issue is a clue for investigation, not evidence of a current universal defect: issue #757.
Only one browser engine fails Engine-specific behavior or a site interaction may be involved. Reproduce with the same Playwright version and compare engines. A historical WebKit report does not establish a current general problem: issue #16727.

7. Performance, reliability, and cost

  • Performance: Wider viewports and full-page images can increase the amount of content rendered or pixels encoded. Use the smallest viewport and output scale that meet the capture requirement.
  • Reliability: Set the viewport before navigation, wait for the page state your capture requires, and log dimensions alongside failures. Keep the browser and Playwright versions consistent when comparing results.
  • Cost: A local Playwright capture has no per-shot API charge, but uses your compute, browser installation, and maintenance time. Hosted screenshot services have their own prices and billing rules; check the provider’s current terms.

8. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a screenshot or PDF; its API accepts the parameter names used by other screenshot APIs to make switching easier. See the ScreenshotNeo API documentation for request options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await require('node:fs/promises').writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
  • Cookie and consent banners, newsletter popups, and chat widgets are removed before capture; each step can be turned off.
  • Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed. Responses identify the page verdict and billing state in headers.
  • An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf.
  • 1,000 screenshots per month are free with no card; paid plans start at $5 for 3,000. All features are on every plan.

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

9. Frequently asked questions

Does fullPage: true include content to the right?

It captures the full scrollable page height. It does not widen the viewport used to render the page.

Should I use a wider viewport or a clip rectangle?

Use a wider viewport when you need the page to lay out as a wider desktop view. Use a clip when you need a known rectangle from content that is already rendered.

Will scale: 'device' reveal missing content?

No. It changes image pixel density, not the page’s CSS layout width.

Is a wide document always a bug?

No. A wide table or other intentionally scrollable component can make the document wider than the viewport. Inspect the source of overflow and match the capture method to the desired image.

Sources