Screenshot one element on a page

Capture only one element of a page, such as a chart, a pricing table or a tweet, with the selector option, and wait for it to render with waitForSelector first.

Updated

This guide shows how to capture one element of a page instead of the whole page, and how to wait for an element that the page renders late.

Capture one element

Set capture.selector to a CSS selector. The image then contains only the first element that matches it.

curl -X POST https://api.wayfern.com/api/v1/screenshot \
  -H "Authorization: Bearer $WAYFERN_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/pricing",
    "capture": {
      "selector": "#pricing-table",
      "format": "png"
    }
  }'

The response has the same shape as a page capture: the image is in data.screenshot, with its url, key, contentType, bytes and expiry times. One element capture costs 5 credits, the same as a page.

Rules for selector:

  • It is a CSS selector, at most 512 characters.
  • When more than one element matches, the first one in the document is captured.
  • The element is captured at its own size. The viewport width still sets the page layout, so the element renders as it does at that width.
  • When nothing matches, the request fails with 404 and error: "not_found", and the message names the selector. It is not charged.

selector cannot be combined with fullPageSlices. That combination is a 400.

Wait for the element first

Pages that build their content with JavaScript often add the element after the first load. Wayfern starts work when the document has loaded, so a late element may not exist yet. Use waitForSelector to wait for it:

curl -X POST https://api.wayfern.com/api/v1/screenshot \
  -H "Authorization: Bearer $WAYFERN_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/dashboard/demo",
    "waitForSelector": "#revenue-chart canvas",
    "capture": {
      "selector": "#revenue-chart",
      "settleMs": 1000
    }
  }'

waitForSelector is a top-level field, next to url. It waits until the element is visible, for at most the request timeout (60 seconds by default for screenshots). If the element never appears, the wait ends and the capture continues. The capture itself then fails with not_found when selector matches nothing.

Two more ways to wait:

  • waitFor: a fixed number of milliseconds after load, from 0 to 30,000.
  • capture.settleMs: milliseconds to wait just before the capture, 250 by default and at most 10,000. Use it for charts and animations that draw after the element appears.

Prepare the page around the element

The page is prepared before the element is captured, in the same way as for a page capture:

  • Cookie banners are dismissed (blockCookieBanners, on by default), so a banner does not cover the element.
  • blockAds blocks ad requests and hides ad slots.
  • hideSelectors hides elements such as a sticky header or a chat button that would overlap the element.
  • click can open a tab or expand a section before the capture.
{
  "url": "https://example.com/product/42",
  "capture": {
    "selector": "#specifications",
    "click": "button[data-tab=specifications]",
    "hideSelectors": ["header.sticky", "#chat-launcher"]
  }
}

The page changes guide explains each option and the order in which they run.

When to use a full page instead

Use an element capture when you know which part of the page you want and its selector is stable. Use a full-page capture when the layout changes often or when you want the context around the element.

To stop on a page that shows an error or a bot wall instead of the element, add capture.failIfContains. The content check guide explains it.

Every field is in the Screenshot API reference, and the limits are on the limits page.