ScreenshotNeo

BlogHow-to

How to Capture Website Screenshots from Indian AWS Regions

Capture websites from Mumbai or Hyderabad with AWS Lambda and Puppeteer or CloudWatch Synthetics. Choose a region, save screenshots, and troubleshoot common issues.

By the ScreenshotNeo team4 October 20267 min read

To capture a website screenshot from an Indian AWS region, run the browser in AWS Mumbai (ap-south-1) or Hyderabad (ap-south-2). For a custom or batch workflow, use a Lambda function with headless Chrome and Puppeteer, then save the image to Amazon S3. For recurring availability and latency checks that retain screenshots, use CloudWatch Synthetics. AWS lists Playwright Lambda layers for both India regions; check the current browser layer and version for your selected region before deploying. AWS regional layer and runtime documentation.

Choose a capture approach

Approach Use it for What it provides
Custom Lambda with Puppeteer On-demand captures, custom capture logic, or batch workflows A headless Chrome screenshot saved to S3; a separate function can fan out work across a list of URLs.
CloudWatch Synthetics Scheduled endpoint availability and latency checks that also retain UI screenshots Managed canaries with screenshot storage and load-time data.

AWS’s architecture example packages Puppeteer and Chrome in a Lambda container. Its capture function receives a URL and bucket name, captures an image, and writes it to S3; a second function can asynchronously invoke it for each URL in a list. Choose the region where the browser should run, and confirm the current regional service, runtime, and browser support before building the deployment.

Deploy a custom Puppeteer capture in Lambda

This approach gives you control over page readiness, screenshot scope, storage keys, and the workflow around each capture. The example below is a minimal handler outline: package it with Puppeteer and a compatible Chrome binary in a Lambda container image, deploy it to the desired India region, and configure its execution role to write to the target S3 bucket. AWS’s reference architecture demonstrates the container-based Puppeteer and Chrome pattern; the exact packaging and runtime configuration depend on the versions you select. AWS Architecture Blog: screenshot service with Puppeteer and Lambda.

const puppeteer = require('puppeteer-core');
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');

const s3 = new S3Client({});

exports.handler = async (event) => {
  const url = event.url;
  const bucket = event.bucket;
  const key = event.key || `screenshots/${Date.now()}.png`;

  if (!url || !bucket) {
    throw new Error('Provide url and bucket in the event');
  }

  let browser;
  try {
    // Configure executablePath and launch arguments for the Chrome binary
    // packaged in your Lambda container image.
    browser = await puppeteer.launch({
      executablePath: process.env.CHROME_EXECUTABLE_PATH,
      headless: true,
      args: ['--no-sandbox', '--disable-setuid-sandbox']
    });

    const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
    page.setDefaultNavigationTimeout(45000);
    await page.goto(url, { waitUntil: 'networkidle2', timeout: 45000 });
    const image = await page.screenshot({ type: 'png', fullPage: true });

    await s3.send(new PutObjectCommand({
      Bucket: bucket,
      Key: key,
      Body: image,
      ContentType: 'image/png'
    }));

    return { bucket, key, contentType: 'image/png' };
  } finally {
    if (browser) await browser.close();
  }
};

Example event:

{
  "url": "https://example.com/",
  "bucket": "your-screenshot-bucket",
  "key": "captures/example-home.png"
}

Set CHROME_EXECUTABLE_PATH to the binary path in your container image, and ensure the installed browser is compatible with the Puppeteer version. Configure the Lambda role with only the S3 write access the function needs. If the target site is private, provide authentication through an appropriate secret-backed flow; do not place credentials in logs or public events.

Set the capture scope and readiness deliberately

The example waits for networkidle2 and captures the full page. Sites with polling, streaming, or long-lived network connections may never reach a network-idle condition. For those pages, navigate using a less strict condition such as domcontentloaded, then wait for a meaningful selector or a fixed, bounded delay before capturing. If the page needs login, establish the authenticated browser state before navigation or use the site’s supported authentication flow.

Playwright documents three useful screenshot scopes: the current viewport, a selected element, and the full scrollable page. Use viewport capture for what a user initially sees, an element capture for a component, and full-page capture for a long page that should be archived as one image. Playwright screenshot documentation.

Run recurring checks with CloudWatch Synthetics

Choose a canary when each capture is part of scheduled endpoint monitoring. AWS describes canaries as checking endpoint availability and latency and storing UI screenshots. Its Synthetics regional layer table lists Playwright layers in Mumbai and Hyderabad. Select the target region, browser, and supported runtime, then use the current layer version and ARN shown for that exact combination. Layer versions are operational details that can change, so verify them at deployment time. CloudWatch Synthetics canary and layer documentation.

Use a custom Lambda when you need your own input format, storage naming, batching, or downstream processing. Use Synthetics when the recurring availability and latency signal is as important as the image itself. Neither approach has a universal cost or speed advantage; compare your capture volume, schedule, browser needs, retention, and current AWS pricing for the resources you configure.

Fan out a batch of URLs

For a large list, avoid trying to open every browser in one invocation. The AWS example separates the work: a coordinator accepts a URL list and asynchronously invokes one capture per URL. Apply concurrency limits appropriate to your account and destination sites, and record per-URL outcomes so one failed page does not hide successful captures. Keep the input list and any credentials out of public invocation paths.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server from ScreenshotNeo. One GET request returns a PNG, JPEG, WebP, or PDF. Its browser runs as a service, so you do not need to package Chrome in Lambda or configure S3 for a basic 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://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,
)
r.raise_for_status()
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 banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed; response headers identify the page verdict and billing status. AI agents can use its MCP server tools to take screenshots, inspect page information, and capture PDFs. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. These examples capture the target site through ScreenshotNeo; use Lambda or Synthetics when the browser itself must originate from a specific AWS region.

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

Region, reliability, and cost considerations

  • Region: Deploy the capture function or canary in Mumbai (ap-south-1) or Hyderabad (ap-south-2) when that is the desired browser location. A regional source IP does not guarantee every visitor in India receives identical content; cookies, account state, DNS, geolocation rules, and edge routing can also affect a response.
  • Network access: Confirm the function has an outbound route to the public sites it captures. If it runs in a VPC, verify the egress path as part of deployment.
  • Storage access: Check the S3 bucket, region, key, and function role when writes fail. Grant only required write permissions.
  • Timeouts: Set navigation and function timeouts with room for slow pages, but keep waits bounded. A page can continue loading indefinitely.
  • Cost: The research does not establish a universal cheaper option. Include compute duration, invocation frequency, storage and retention, monitoring usage, and any networking charges in your own estimate. Check current AWS pricing for the selected region and configuration.
  • Reliability: Return or record a result per URL, use bounded retries for transient failures, and avoid treating a successful browser launch as proof that the intended page state was captured. Keep browser and runtime versions aligned.

Troubleshooting

Symptom Likely cause What to check
Lambda cannot launch Chrome The binary path is wrong, the binary is absent, or the packaged browser does not match the Puppeteer setup. Inspect the container image, executable path, file permissions, and browser/Puppeteer compatibility.
Navigation times out The site is slow, blocked, or keeps network requests open. Confirm outbound access, use a suitable navigation readiness condition, and wait for a page-specific selector with a bounded timeout.
Screenshot is blank or incomplete The page has not rendered the required content, lazy-loaded content is below the fold, or authentication failed. Wait for the relevant selector, scroll as needed to trigger lazy loading, and verify the authenticated state and target URL.
S3 write is denied The execution role, bucket, or key configuration does not allow the write. Check the bucket name and region, role policy, bucket policy, and object key.
Synthetics cannot find the browser layer The layer ARN or version is for another region, browser, or runtime, or it has changed. Recheck the current Synthetics regional layer table for the selected region and browser.
India users see different content than the capture Regional egress alone does not determine content; cookies, account state, DNS, geolocation rules, and edge routing may vary. Make browser state explicit and compare the target site’s behavior under the relevant conditions.

FAQ

Can CloudWatch Synthetics capture screenshots in both Mumbai and Hyderabad?

AWS’s regional layer table lists Playwright layers for both ap-south-1 and ap-south-2. Confirm the current layer and runtime version before deployment.

Should I use Lambda or a canary for a one-off screenshot?

A custom Lambda is suited to an on-demand capture or custom workflow. Synthetics is designed for recurring endpoint checks that also retain screenshots.

Does running the browser in India guarantee the same page every Indian user sees?

No. Regional egress is one input; browser state, DNS, geolocation rules, and the site’s edge routing can also change what the page returns.