ScreenshotNeo

BlogHow-to

How to Set a Custom Viewport for Webpage Screenshots in n8n

Set the browser viewport before navigation to capture the responsive layout you need. Compare Puppeteer, n8n community nodes, and a hosted screenshot API.

By the ScreenshotNeo team4 October 20269 min read

To set a custom viewport for webpage screenshots in n8n, configure the browser’s viewport width and height before navigating to the target URL. With Puppeteer, call page.setViewport({ width, height, deviceScaleFactor }) before page.goto(). The viewport controls the page’s CSS-pixel dimensions and therefore which responsive layout the browser renders. A full-page screenshot is a separate choice from the viewport size.

How you apply that setting depends on your n8n hosting: a self-hosted Code node, a community node with a viewport field, or a hosted screenshot API node. For self-hosted browser automation, Puppeteer gives direct control. For n8n Cloud, do not assume that external npm imports are available in the Code node.

1. Choose an n8n approach

Approach Good fit when Check before using
Puppeteer in a Code node You self-host n8n and can configure the package and compatible Chrome or Chromium runtime. External npm modules, browser installation, and task-runner configuration must all work in your deployment.
n8n-nodes-html2image You want a Puppeteer-based community node with a Viewport width and height setting. Check current maintenance and compatibility. Docker deployments need Puppeteer installed in the image, according to the project README.
n8n-nodes-getscreenshot You prefer a hosted capture API exposed through a community node. It requires a GetScreenshot API key. Review that provider’s current data handling and usage terms.

n8n’s Code node documentation distinguishes self-hosted installations, which can be configured to import external npm modules, from n8n Cloud, which does not allow those imports. Check the n8n Code node documentation for the current requirements. Community nodes are third-party packages; verify their compatibility with your n8n version before relying on them in a production workflow.

2. Set the viewport with Puppeteer

This standalone Node.js example shows the essential order. In an n8n Code node, adapt the browser-launch and output portions to the APIs available in your installed n8n version and deployment. The viewport configuration itself is the Puppeteer page.setViewport() call.

const puppeteer = require('puppeteer');

async function capture(url, outputPath) {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();

    // Set the viewport before navigation so responsive sites render
    // at the intended CSS-pixel width and height.
    await page.setViewport({
      width: 1440,
      height: 900,
      deviceScaleFactor: 1,
    });

    await page.goto(url, {
      waitUntil: 'networkidle2',
      timeout: 60000,
    });

    await page.screenshot({
      path: outputPath,
      type: 'png',
      fullPage: false,
    });
  } finally {
    await browser.close();
  }
}

capture('https://example.com', '/tmp/page.png').catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

Puppeteer recommends setting the viewport before navigation because some sites respond to phone-sized viewports by changing their behavior. See the Puppeteer Page.setViewport() API.

Use it in a self-hosted n8n Code node

  1. Confirm external npm modules are enabled and available to the Code node’s runtime in your deployment.
  2. Install/configure Puppeteer and a compatible browser in the environment that actually runs the node or task runner.
  3. Create a page, set the viewport, navigate, wait for the content you need, and capture.
  4. Return or store the screenshot using a binary-data mechanism supported by your n8n version and workflow.

Code-node APIs for returning binary files and external module configuration can vary by n8n version and execution mode. Keep the screenshot logic separate from the version-specific binary-output plumbing, and use the official documentation for your installed version. A report in the n8n issue tracker describes an import failure in one v2 external task-runner setup; treat it as a setup-specific warning, not proof that all task runners fail. See n8n issue 26926.

Full-page capture versus viewport capture

fullPage: false captures the visible viewport. Set fullPage: true when you want the page’s full vertical content. This does not change the initial viewport used to lay out the page. A separate image-resize operation changes the resulting file dimensions; it does not make the website render at another responsive breakpoint.

3. Set custom dimensions in a community node

Puppeteer-based HTML to image node

The n8n-nodes-html2image community node documents a Viewport setting in pixels with width and height. Its screenshot controls also include a CSS selector, image type, quality, and a Full Page option. That can be a simpler setup when you want to configure the capture in a node interface rather than write browser code.

Review its project README for installation and current compatibility details. The README notes that Docker deployments need Puppeteer installed in the image. Since this is a third-party node, check its current maintenance status and test it against your n8n release.

Hosted screenshot API node

The n8n-nodes-getscreenshot community node documents custom width and height, device scale factor, device presets, output formats, and timing controls. It requires a GetScreenshot API key and returns screenshot output as binary data. See the project README for its documented options.

A hosted node avoids managing the browser runtime yourself, but adds an external service dependency. Before sending target URLs or related data to any provider, review its current terms and data handling. The research for this article did not verify that provider’s pricing, retention terms, or service-level commitments.

4. Choose dimensions and capture behavior

Setting What it controls Practical note
width, height Viewport dimensions in CSS pixels. Choose dimensions that trigger the responsive layout you need. Set them before navigation.
deviceScaleFactor Ratio of device pixels to CSS pixels. Use a larger factor when you need higher pixel density; output pixel dimensions and file size increase.
Full-page setting Whether the capture extends beyond the visible viewport. Choose independently of viewport dimensions.
Image type and quality Encoding format and, for lossy formats, compression quality where exposed. Use the format and quality options the chosen node supports; compare output size with the detail required.
Selector capture A specific page element rather than the full viewport. Wait for the element to exist and be visible before capture.

For example, a 390 × 844 CSS-pixel viewport asks the page to render a narrow mobile layout. A 1440 × 900 viewport asks for a desktop-sized layout. With deviceScaleFactor: 2, the browser renders at twice the device-pixel density for each CSS pixel; this is not the same as doubling the CSS viewport width.

5. Wait for the right page state

Navigation completing does not always mean the content you want is ready. Pages may load data after the initial document, render images lazily, or keep network connections open. Choose a wait strategy that matches the page and your workflow:

  • Use a navigation wait condition appropriate to the site. networkidle2 can be useful for pages that settle, but persistent requests may prevent network-idle conditions from completing.
  • Wait for a known selector when the screenshot depends on a specific element.
  • Use a bounded timeout. Avoid an unbounded wait that can leave workflow executions stuck.
  • For lazy-loaded content, scroll or otherwise trigger the content before taking a full-page screenshot if the page requires it.

When connecting Puppeteer to remote browser infrastructure, configure the connection for the endpoint and authentication method supplied by that provider. An n8n issue includes one user’s Browserless WebSocket example, but it is an example report rather than a current compatibility guarantee: issue 26926.

6. Troubleshooting custom viewport screenshots

Symptom Likely cause Fix
The page still looks like desktop after setting mobile dimensions. The viewport was set after navigation, or the requested width does not cross the site’s responsive breakpoint. Set the viewport before goto(); confirm the intended CSS-pixel width and the site’s breakpoints.
Importing Puppeteer fails in the Code node. External modules may not be available in that hosting mode, or the package is not configured in the runtime that executes the node. Check n8n’s Code node rules for your hosting type and task-runner setup. For n8n Cloud, use a supported node or hosted capture approach rather than assuming external npm imports work.
Puppeteer launches but cannot find Chrome or Chromium. The browser binary is missing or unavailable to the execution environment. Install/configure a compatible browser where the node runs, or use a community node or hosted service that manages capture infrastructure.
Navigation times out on a page that appears loaded. The selected wait condition may never resolve because the page keeps requests open, or the timeout is too short. Use a bounded timeout and wait for a relevant selector or another appropriate page state instead of relying only on network idle.
A full-page screenshot misses images or sections. Content may load lazily as the page scrolls, or capture may occur before asynchronous rendering completes. Trigger the page’s lazy loading and wait for the required content before capturing.
The screenshot file is too large or too small in pixels. Device scale factor or image resizing changed output density or dimensions. Adjust deviceScaleFactor for pixel density. Use a different viewport to change responsive layout; post-capture resizing alone does not do that.
A community node is missing or incompatible. The package may not support the installed n8n version or deployment mode. Check the project’s current README and compatibility notes. Test the workflow after upgrades.
A remote browser connection fails. The endpoint, credentials, network access, or expected connection method may be wrong. Verify the provider’s current connection instructions and reachability from the n8n runtime. Do not treat an issue comment as a compatibility guarantee.

7. Performance, reliability, and cost

  • Viewport and image size: Larger dimensions and higher device scale factors produce more pixels to encode and move through the workflow. Use the smallest values that meet the capture requirement.
  • Full-page work: Full-page captures can involve more page content and a larger image than viewport captures. Use full-page mode only when the whole document is needed.
  • Wait strategy: Long waits increase execution time; overly short waits produce incomplete screenshots. Wait for the relevant content with a timeout suited to your workflow.
  • Browser reliability: Self-hosted Puppeteer requires a compatible browser and runtime configuration. Validate those together after changing n8n versions, containers, or task-runner settings.
  • External service dependency: A hosted API shifts browser operations out of your n8n deployment, while adding dependency on the service and its current terms. Review data handling and usage costs before adoption.

The cited n8n and Puppeteer material does not provide a general capture benchmark or universal cost comparison. Actual execution time, resource use, and service cost depend on the target page, capture settings, hosting, and provider terms.

8. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. Its API accepts a URL in one GET request and returns an image or PDF. The request below uses the documented endpoint and Python example form; replace the target URL and API key. See the ScreenshotNeo API documentation for options and setup.

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}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));

ScreenshotNeo accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, and failed loads are never billed, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up free for 1,000 screenshots a month, with no card required.

Frequently asked questions

Does changing the viewport resize the screenshot after capture?

No. The viewport sets the browser’s CSS-pixel page area and influences the responsive layout. Resizing the resulting image changes its dimensions without asking the page to render at another breakpoint.

Can I use this method on n8n Cloud?

The direct Code node approach depends on importing Puppeteer, and n8n’s documentation says Cloud does not allow external npm module imports. Use an available supported community node or hosted capture option if it meets your workflow needs.

Is full-page capture the same as a tall viewport?

No. Viewport dimensions set the initial browser page area. Full-page capture controls whether the screenshot extends beyond the visible area.

What dimensions should I choose?

Choose CSS-pixel dimensions that match the responsive breakpoint or device layout you need to inspect. Use device scale factor separately when output pixel density matters.