BlogScreenshots on your device
How to Take a Desktop Layout Screenshot of an Indian Website with Chrome Headless
Capture an Indian website at a desktop-sized browser viewport with Chrome Headless, or use Puppeteer when you need full-page capture and repeatable control.
Quick answer: Run Chrome with --headless --screenshot --window-size=WIDTH,HEIGHT, followed by the page URL. For example:
chrome --headless --screenshot --window-size=1440,900 "https://example.in/"
Chrome saves screenshot.png in the current working directory by default. Replace chrome with your installed executable name if needed. The dimensions configure the browser window or viewport for the capture; they do not make the request come from India or determine which country-specific version of a site you receive.
For a one-off viewport screenshot, the Chrome command line is the shortest route. Use Puppeteer when you need repeatable scripts, explicit wait conditions, or a full-page screenshot. Chrome documents the --screenshot and --window-size flags, including a 1280 by 1696 example; that example is not a universal desktop size. Chrome Headless command-line reference.
1. Choose the desktop viewport
A viewport is the page area Chrome lays out and renders for the capture. Choose dimensions to match the question you are answering: checking a responsive breakpoint, recording a dashboard layout, or producing an image for a report. There is no single desktop viewport established for all Indian websites. A width such as 1440 pixels can be a useful starting point for a desktop-oriented check, but choose the dimensions that match your actual target.
The CLI flag accepts width and height in pixels as a comma-separated pair: --window-size=WIDTH,HEIGHT. A taller height shows more of the page in the initial viewport; it does not automatically capture content extending below it. The documented Chrome example uses --window-size=1280,1696, which illustrates the syntax, not a recommended standard.
| Goal | What to set | What the result means |
|---|---|---|
| Inspect a desktop layout | A task-specific width and height | A screenshot of the rendered viewport |
| Compare a responsive breakpoint | Capture at each width you need to compare | Separate renders at those viewport sizes |
| Capture the entire long page | Use Puppeteer with fullPage: true |
A full-page image, rather than only the initial viewport |
2. Take a screenshot with Chrome Headless
One-off capture
Open a terminal, change to the folder where you want the image saved, and run:
chrome --headless --screenshot --window-size=1440,900 "https://example.in/"
Use your target URL in place of https://example.in/. The URL should include the scheme, usually https://. The default file is screenshot.png in the current working directory. Check that directory after the command completes.
Find the Chrome executable
The executable name varies by operating system and installation. Common names include chrome, google-chrome, google-chrome-stable, and chromium. Use the name or full path available on your machine. If the command is not found, locate the installed browser or use Puppeteer, which can manage a compatible browser installation.
Wait for a page that loads slowly
Chrome’s current Headless CLI reference documents --timeout for screenshot capture. It sets the maximum wait in milliseconds before Chrome captures even if the page is still loading:
chrome --headless --screenshot --window-size=1440,900 --timeout=10000 "https://example.in/"
This is a time limit, not proof that every asynchronous component is ready. Inspect the resulting image. If a page needs a particular selector, interaction, or more tailored wait logic, use Puppeteer.
Save the output where you need it
The documented default is screenshot.png in the current directory. Run Chrome from the destination folder. CLI output-path options can vary by Chrome version, so check the current command-line reference for your installed version before relying on a particular flag. With Puppeteer, set the path option explicitly.
3. Capture a full page or automate with Puppeteer
Chrome’s basic CLI screenshot example captures the current browser view. For a full-page image or repeatable capture script, Puppeteer exposes page.screenshot(); its fullPage option defaults to false. Set it to true to capture the full page. See the Puppeteer screenshot guide and ScreenshotOptions reference.
Runnable Node.js example
Install Node.js, make a project folder, then install Puppeteer. The package includes a compatible browser download as part of its normal installation flow.
mkdir desktop-shot
cd desktop-shot
npm init -y
npm install puppeteer
Save this as screenshot.mjs:
import puppeteer from 'puppeteer';
const url = process.argv[2] ?? 'https://example.in/';
const browser = await puppeteer.launch({ headless: true });
try {
const page = await browser.newPage();
await page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 });
await page.goto(url, {
waitUntil: 'networkidle2',
timeout: 60000,
});
await page.screenshot({
path: 'desktop.png',
type: 'png',
fullPage: false,
});
} finally {
await browser.close();
}
Run it with:
node screenshot.mjs "https://example.in/"
To capture the entire page, change fullPage: false to fullPage: true. The networkidle2 navigation condition waits for network activity to become quiet according to Puppeteer’s lifecycle rules; sites with ongoing requests may not reach that state promptly. For those pages, navigate with a different lifecycle condition and wait for a page-specific selector or a deliberate delay.
Python and Node.js alternatives without Puppeteer
Chrome Headless is the browser doing the rendering. The examples below invoke its CLI from another language; they are convenient wrappers, not separate browser automation libraries. They capture the viewport and use the CLI’s default output filename. The Python example uses subprocess.run with an argument list so the URL is not interpreted by a shell.
import subprocess
url = "https://example.in/"
subprocess.run(
[
"chrome",
"--headless",
"--screenshot",
"--window-size=1440,900",
url,
],
check=True,
timeout=90,
)
print("Saved screenshot.png in the current working directory")
For Node.js, save as capture.mjs and run with node capture.mjs:
import { spawnSync } from 'node:child_process';
const url = 'https://example.in/';
const result = spawnSync(
'chrome',
['--headless', '--screenshot', '--window-size=1440,900', url],
{ stdio: 'inherit', timeout: 90000 },
);
if (result.error) throw result.error;
if (result.status !== 0) {
throw new Error(`Chrome exited with status ${result.status}`);
}
console.log('Saved screenshot.png in the current working directory');
If your browser executable has a different name, replace chrome in these examples. These CLI wrappers do not provide Puppeteer’s fullPage option or page-level selector waits.
4. Account for what “Indian website” means
A desktop viewport controls layout dimensions, not visitor location. The Chrome command-line documentation does not establish that a request is served from India or that the result matches what a visitor in India sees. A website may vary content based on network location, account state, language, consent choice, cookies, or other request context. Check those conditions on the actual target instead of assuming a viewport setting controls them.
For a location-specific page, record the conditions that matter to your task: the URL, viewport, browser version, whether you are logged in, relevant cookies or consent state, and the environment from which Chrome makes the request. If you need a specific locale or account view, configure and verify that separately; a window-size flag does not set it.
5. Check the capture before relying on it
Chrome executes page scripts as it renders a page, but that does not guarantee every asynchronous or lazy-loaded element is ready by the time a screenshot is taken. The Chrome documentation describes how --dump-dom runs scripts that can alter the DOM before serialization; that behavior is not a guarantee that all network activity or delayed content has settled. See the Headless CLI reference.
- Menus and overlays: Check whether a menu, cookie notice, newsletter popup, or chat widget covers the content you need.
- Fonts and images: Look for fallback fonts, blank image areas, or images that have not loaded.
- Scroll-dependent content: Lazy images or sections activated by scrolling may not appear in a viewport-only capture.
- Page state: Confirm the page is not showing a login screen, error page, or location-specific variation different from your intended state.
- Dimensions: Check the screenshot’s pixel dimensions and whether the layout matches the viewport you selected.
For a repeatable workflow, save the URL, viewport, capture time, browser version, and relevant page state alongside the image. This makes comparisons easier to interpret when a site changes.
6. Troubleshooting
| Symptom | Likely cause | What to try |
|---|---|---|
chrome: command not found |
Chrome is not on the executable search path, or the installed browser uses another name. | Use the installed executable name or full path. On Linux, installations may provide google-chrome, google-chrome-stable, or chromium. |
| No screenshot appears | The command failed, the working directory is unexpected, or the output file is elsewhere. | Run from the intended folder, check the process exit status and error output, and look for screenshot.png in the current directory. |
| Screenshot shows only part of the page | A viewport capture is being mistaken for a full-page capture. | Use Puppeteer with fullPage: true when you need the full document. |
| Content is missing or still loading | Late scripts, image loading, or ongoing requests outlasted the capture wait. | Increase the CLI timeout or use Puppeteer to wait for a meaningful selector or page-specific condition. Check the final image. |
| Chrome exits with a navigation or timeout error | The URL may be unreachable from the capture environment, or the page did not finish within the configured limit. | Check the URL and connectivity from the machine running Chrome. For Puppeteer, adjust the navigation timeout and wait strategy to match the page. |
| The layout differs from a local desktop browser | Viewport, device scale, browser version, fonts, cookies, login, or location-dependent responses may differ. | Match the relevant conditions one by one. Do not treat viewport size as a location setting. |
| Images appear blank in a full-page capture | Images may be lazy-loaded only after scrolling. | Use a script that scrolls through the page before capture, then wait for images to load; verify the output because site behavior varies. |
| Automation hangs waiting for network idle | Analytics, streaming, or other persistent requests keep the network active. | Use a different navigation lifecycle and wait for a specific selector or bounded delay instead of requiring network idle. |
7. Performance, reliability, and cost
A single CLI invocation is simple for occasional captures. Repeated jobs benefit from keeping a browser process alive in an automation script instead of repeatedly starting Chrome, while still closing pages and browsers cleanly when work finishes. Full-page screenshots can use more memory and produce larger files as page height grows. Reduce capture frequency, dimensions, or output format only when that remains useful for your task.
Reliability depends on the page and capture environment: network availability, page scripts, fonts, authentication, and lazy loading can all affect the result. A successful process exit is not a visual quality check, so inspect important captures. The do-it-yourself approach has no per-shot ScreenshotNeo charge, but you operate the browser, handle failures, and manage storage and runtime yourself. Chrome and Puppeteer documentation do not specify a universal capture time or resource requirement.
8. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. One GET request can return a PNG, JPEG, WebP, or PDF. Its capture options include viewport sizing, full-page capture, device presets, waiting for selectors or network idle, custom headers and cookies, and more. See the ScreenshotNeo API documentation.
cURL:
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,
)
r.raise_for_status()
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}`);
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));
With ScreenshotNeo, cookie banners and consent notices, popups, and chat widgets are removed before the shot; each of those cleanup steps can be turned off. Bot checks, blank pages, and failed loads are not billed, and response headers report the page verdict and billing status. An MCP server lets AI agents use screenshot tools. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Create a free account and get 1,000 screenshots a month with no card.
9. Frequently asked questions
Does this command make the website think I am browsing from India?
No. --window-size sets the browser window dimensions. It does not establish the request’s network location.
Does a larger window capture the whole webpage?
No. A larger viewport displays more of the page at once, but a long page needs full-page capture, such as Puppeteer’s fullPage: true.
What is the default screenshot filename?
Chrome’s documented CLI default is screenshot.png, saved in the current working directory.
Can I use the documented 1280 by 1696 size for every site?
You can, but it is only an example in Chrome’s documentation. Select dimensions based on the layout or breakpoint you need to inspect.
Can Headless Chrome work without a physical monitor?
Yes. Chrome documents a configurable virtual screen for Headless mode that is independent of attached physical displays. That concerns screen configuration, not the network location of a request. See Chrome’s virtual screen configuration guide.


