ScreenshotNeo

BlogHow-to

How to Capture a Mobile-Width Screenshot of an Indian Website with BrowserCat

Set a mobile viewport in Playwright, connect through BrowserCat, and capture an Indian website. Learn when device emulation or an India-based proxy is needed.

By the ScreenshotNeo team4 October 20269 min read

To capture an Indian website at mobile width with BrowserCat, connect Playwright to BrowserCat’s hosted Chromium browser, create a browser context with the viewport dimensions you want, navigate to the site, and call page.screenshot(). For example, a 390 × 844 viewport produces a mobile-width responsive-layout capture; it does not by itself make the browser appear to be in India or fully emulate a specific phone.

BrowserCat provides the remote browser connection; Playwright controls the page and screenshot. The example below captures the visible viewport as a PNG. Set fullPage: true if you need the entire page instead. See the BrowserCat Quick Start and the Playwright screenshot API.

1. Set up BrowserCat and Playwright

  1. Create a BrowserCat account and obtain an API key.
  2. Install Node.js and the Playwright Chromium client package.
  3. Store the API key in an environment variable named BROWSERCAT_API_KEY. Do not commit it to source control or expose it in a browser application.
npm install playwright-core

Run the following as an ES module, for example in a file named capture.mjs. It saves mobile.png in the current directory.

import * as pw from 'playwright-core';

const apiKey = process.env.BROWSERCAT_API_KEY;
if (!apiKey) throw new Error('Set BROWSERCAT_API_KEY before running this script.');

const browser = await pw.chromium.connect(
  'wss://api.browsercat.com/connect',
  { headers: { 'Api-Key': apiKey } }
);

try {
  const context = await browser.newContext({
    viewport: { width: 390, height: 844 }
  });
  const page = await context.newPage();

  await page.goto('https://example.in', { waitUntil: 'load' });
  await page.screenshot({ path: 'mobile.png', fullPage: false });
} finally {
  await browser.close();
}

Set the secret and run the script in your shell, using the equivalent environment-variable syntax for your operating system:

BROWSERCAT_API_KEY=your_api_key node capture.mjs

The dimensions are an example, not a BrowserCat-prescribed India setting or an exact model of a particular handset. Use the viewport width and height that match the responsive layout you need to inspect. Set the viewport when creating the context, before navigation, because the site may choose its layout during page load.

2. Choose what “mobile screenshot” means

A mobile-width screenshot can mean a responsive layout at a particular CSS viewport, an emulation of a named device, a full-page capture, or a view served specifically to visitors in India. These goals require different settings.

Goal Configuration What it tells you
Check a responsive breakpoint Set viewport width and height on the context How the page lays out at that CSS viewport. It does not imply a mobile user agent, touch behavior, or Indian IP address.
Approximate a specific mobile device Use a Playwright device descriptor or explicitly configure device properties Can emulate properties such as viewport, screen size, user agent, and touch. Consult Playwright’s emulation guide for device descriptors and supported settings.
Capture the first screen Leave fullPage false The visible viewport at the time of capture.
Capture a long page Set fullPage: true The full scrollable page. Very long pages can produce large images and take longer to render and save.
See content for an India-based visitor Route traffic through an appropriate third-party proxy A geographic-routing attempt. A narrow viewport alone does not change the browser’s public IP location.

Playwright also supports locale and timezone emulation. Those settings can affect formatting and client-side behavior, but they do not change the browser’s network location. Set only the properties relevant to the question you are testing.

3. Wait for the content you need

waitUntil: 'load' waits for the page load event, but a site may render important content afterward through client-side code, delayed requests, or user interaction. When that happens, wait for the target content or for the application’s own ready condition before capturing.

await page.goto('https://example.in', { waitUntil: 'load' });
await page.locator('main article').waitFor({ state: 'visible' });
await page.screenshot({ path: 'article.png' });

Replace main article with a selector that identifies the content you need. For a site whose content appears after a known interaction, perform that interaction and wait for its result. Avoid relying on an arbitrary delay when a meaningful selector or page-ready condition is available.

4. Capture the viewport or the full page

The default screenshot is the visible viewport. Pass fullPage: true to capture the complete scrollable page:

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

Full-page capture can create a tall, memory-intensive image on long pages. If the goal is to inspect mobile layout, a viewport screenshot is often easier to compare across widths. If the goal is to archive an article, full-page capture may be more appropriate.

5. When the page must appear to come from India

BrowserCat’s region documentation says sessions are placed automatically near the request and that explicit region pinning is not currently available. Its documented route to precise geographic control is a third-party proxy configured separately through BrowserCat’s connection options. See BrowserCat’s browser region documentation and its third-party proxy documentation.

This distinction matters when the site varies content by IP location, blocks requests from outside India, or serves region-specific pages. A mobile viewport changes the requested layout; it does not make the session’s IP Indian. Proxy availability, credentials, and routing behavior depend on the proxy provider. Keep proxy credentials private and follow that provider’s configuration instructions.

6. BrowserCat configuration and practical limits

  • Connection: BrowserCat’s Playwright workflow connects Chromium to wss://api.browsercat.com/connect and authenticates with the Api-Key header. Keep the connection on WSS and protect the key.
  • Configuration options: BrowserCat documents configuration through the BrowserCat-Opts header or query parameters. If both are supplied, the header takes precedence. Use the options relevant to your session, and consult the configuration reference for current names and formats.
  • Browser engines: BrowserCat documents Chromium and Chrome support; Firefox and WebKit are listed as forthcoming in its browser type documentation. Do not assume another engine is available for this workflow.
  • Authentication: Prefer the API-key header shown above. BrowserCat advises using HTTPS/WSS if authenticating through query parameters, since those parameters can be exposed in logs or other places.
  • India-specific results: Device locale, timezone, and viewport can influence page behavior, but only network routing addresses IP-based location differences.

7. cURL, Python, and a local Playwright alternative

BrowserCat’s documented workflow is a remote browser connection controlled by Playwright, so a plain HTTP cURL or Python request cannot substitute for the browser session and run its page JavaScript. These examples show how to connect with the same hosted Chromium approach from JavaScript or Python, and how a cURL request can check whether a page responds over HTTP.

Node.js with BrowserCat

The complete BrowserCat capture script is in section 1. The essential sequence is: connect to the WebSocket endpoint, create a context with the desired viewport, navigate, wait for the relevant content, then call page.screenshot().

Python with Playwright

Install Playwright and its Python package, then use Playwright’s Chromium connection support with the BrowserCat endpoint and API-key header. Check BrowserCat’s current documentation for Python-specific connection compatibility and package requirements before relying on this workflow.

import asyncio
import os
from playwright.async_api import async_playwright

async def main():
    api_key = os.environ.get("BROWSERCAT_API_KEY")
    if not api_key:
        raise RuntimeError("Set BROWSERCAT_API_KEY before running this script.")

    async with async_playwright() as p:
        browser = await p.chromium.connect(
            "wss://api.browsercat.com/connect",
            headers={"Api-Key": api_key},
        )
        try:
            context = await browser.new_context(
                viewport={"width": 390, "height": 844}
            )
            page = await context.new_page()
            await page.goto("https://example.in", wait_until="load")
            await page.screenshot(path="mobile.png", full_page=False)
        finally:
            await browser.close()

asyncio.run(main())

cURL for an HTTP response check

This request checks the public page response; it does not render a browser screenshot or prove that a mobile layout looks correct:

curl -L --max-time 30 -o page.html -w 'HTTP %{http_code}\n' https://example.in/

Use BrowserCat plus Playwright when you need a rendered page screenshot, including client-side content and viewport-dependent layout.

8. Troubleshooting

Symptom Likely cause What to try
Connection rejected or unauthorized Missing, invalid, expired, or incorrectly named API key Confirm BROWSERCAT_API_KEY is set in the process environment and sent as the Api-Key header. Recheck the key in BrowserCat.
WebSocket connection fails Incorrect endpoint, network restrictions, or a connection setup issue Use wss://api.browsercat.com/connect, check that outbound secure WebSockets are allowed, and review BrowserCat’s connection instructions.
Screenshot shows desktop layout The viewport was set after navigation, the requested width was not applied, or the site uses a different breakpoint Set the context viewport before opening the page; confirm the width; then inspect the site’s responsive breakpoints.
Page is missing dynamic content The screenshot ran after the load event but before the relevant content appeared Wait for a content selector or application-ready condition before calling screenshot().
Content differs from an India visit The browser session is not routed through an India-based IP Use a third-party proxy with the required location and configure it through BrowserCat’s documented proxy options. Viewport and locale settings do not set IP geography.
Capture is too tall or slow fullPage: true is capturing a long page Use a viewport capture if that answers the question, or capture a specific page state or section where appropriate.
Page looks wrong only on a real phone Viewport sizing alone does not emulate all device behavior Use a Playwright device descriptor or configure the needed user agent, screen, and touch properties. Compare against the real device when behavior depends on hardware or browser differences.

9. Performance, reliability, and cost considerations

Remote browser capture includes connection setup, page navigation, rendering, and image transfer. Reuse a session for multiple captures when your workload and BrowserCat’s session guidance permit it; close browser connections when finished. Wait for the minimum page condition that makes the screenshot useful rather than adding fixed delays to every capture.

For more reliable results, use a stable URL, an explicit viewport, and a page-specific readiness condition. A site can still change its markup, content, or access rules, so selectors may need maintenance. If the capture is part of a recurring job, record the target URL, viewport, timestamp, and failure details so a changed page can be distinguished from a connection problem.

BrowserCat’s pricing and service limits are not specified in the research for this article. Check its current plan and usage documentation before estimating costs for a production workload. Also account for any separate proxy charges if geographic routing is required.

10. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. A single GET request captures a page without setting up a remote Playwright browser. Use it when you need a screenshot of a publicly reachable page and the provided viewport controls are sufficient for your task. For an Indian-IP-specific response, confirm the required network location separately; a screenshot API call should not be assumed to provide India-based routing.

See the ScreenshotNeo API documentation for request options. This cURL example saves a WebP capture of an Indian website:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.in -o shot.webp

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.in"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.in' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each of those steps can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. Its 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.

Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.

11. FAQ

Does a .in domain guarantee the page is served from India?

No. The domain does not determine the cloud browser’s IP location. If the site personalizes or restricts content by IP, use a suitable proxy and verify the response.

Is 390 pixels the correct mobile width for every Indian website?

No. It is an illustrative viewport. Choose the width your responsive test targets, or use a device descriptor when you need to approximate a particular device.

Will fullPage: true include content that loads only after scrolling?

Do not assume it will trigger every site’s lazy-loading behavior. If lower-page content matters, scroll or otherwise prompt the site to load it, wait for that content, and then capture.

Can I use BrowserCat to test Firefox or WebKit today?

BrowserCat’s documented browser types list Chromium and Chrome as supported, with Firefox and WebKit forthcoming. Check its current documentation for changes.