ScreenshotNeo

BlogHow-to

How to Set an Indian Locale and Timezone for Puppeteer Screenshots

Set Puppeteer’s locale to en-IN and timezone to Asia/Kolkata before navigation. Learn how to verify the output and handle common rendering issues.

By the ScreenshotNeo team4 October 20267 min read

Set Puppeteer’s locale and timezone separately, and await both settings before navigating: use page.emulateLocale('en-IN') for English-language India regional behavior and page.emulateTimezone('Asia/Kolkata') for India time. Then load the page, wait for the content you need, and capture it with page.screenshot().

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
try {
  const page = await browser.newPage();

  await page.emulateLocale('en-IN');
  await page.emulateTimezone('Asia/Kolkata');
  await page.goto('https://example.com', { waitUntil: 'networkidle0' });

  await page.screenshot({ path: 'india.png', fullPage: true });
} finally {
  await browser.close();
}

These are page-level browser emulation settings. They do not give the browser an Indian IP address, establish physical location, or guarantee that a site’s server will return India-specific content. Validate the rendered page in the Puppeteer and browser versions used by your project.

1. What locale and timezone change

Locale and timezone are separate settings. A locale can influence language and regional formatting exposed to page code, such as how dates and numbers are formatted. A timezone affects browser date and time behavior. Neither setting is the same as viewport or device emulation, and neither proves geographic location to a website.

en-IN is a practical starting locale for English-language India behavior; Asia/Kolkata is the timezone identifier to use for India time. Puppeteer’s API describes the mechanisms generically, so check the actual formatting and page behavior in your installed runtime rather than assuming every site will use the values in the same way.

2. Install and run Puppeteer

In a new project, install Puppeteer and save the following as capture.mjs:

npm install puppeteer
import puppeteer from 'puppeteer';

const targetUrl = process.argv[2] ?? 'https://example.com';
const browser = await puppeteer.launch();

try {
  const page = await browser.newPage();
  await page.emulateLocale('en-IN');
  await page.emulateTimezone('Asia/Kolkata');
  await page.goto(targetUrl, { waitUntil: 'networkidle0' });
  await page.screenshot({ path: 'india.png', fullPage: true });
} finally {
  await browser.close();
}

Run it with node capture.mjs https://example.com. The API references list different current versions for locale, timezone, and screenshot methods. Confirm that your installed Puppeteer version supports the methods, and use that version’s documentation as the authority for your deployment.

3. Set both values before navigation

  1. Create the browser page.
  2. Await page.emulateLocale('en-IN').
  3. Await page.emulateTimezone('Asia/Kolkata').
  4. Navigate to the target URL.
  5. Wait for the content your screenshot depends on, then take the screenshot.

Applying both settings before navigation helps make the initial page rendering use the desired browser emulation. If the page changes locale or time after loading through its own application logic, wait for that update before capture as well.

4. Verify the browser values and rendered output

Inspect the browser’s resolved locale and timezone from page JavaScript. This small check can help distinguish an emulation problem from a site that ignores browser locale settings:

const browserSettings = await page.evaluate(() => ({
  locale: Intl.DateTimeFormat().resolvedOptions().locale,
  timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
  formattedDate: new Intl.DateTimeFormat(undefined, {
    dateStyle: 'full',
    timeStyle: 'long'
  }).format(new Date()),
  formattedNumber: new Intl.NumberFormat().format(1234567.89)
}));

console.log(browserSettings);

Also inspect the screenshot itself. The resolved values show what the browser reports to page code; they do not prove that the site uses those values for its displayed content. A server-rendered date, fixed text, saved account preference, or application-specific setting may take precedence.

5. Choose screenshot extent and wait conditions

fullPage: true captures beyond the viewport; it changes screenshot dimensions, not locale or timezone. Omit it or set it to false for a viewport-sized image. Puppeteer documents false as the default.

networkidle0 can be useful for pages that finish loading their requests, but some sites keep network connections open or load content later. For those pages, wait for a known selector instead of relying only on network idleness:

await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
await page.waitForSelector('[data-ready="true"]', { timeout: 15000 });
await page.screenshot({ path: 'india.png', fullPage: true });

Replace the selector with one that indicates the actual content is ready. If content appears after a known delay, a bounded page.waitForTimeout() may be appropriate for your installed Puppeteer version, but a meaningful page condition is generally more reliable than an arbitrary pause.

6. Locale and timezone are not geolocation

These calls emulate browser locale and timezone. They do not change the network route or IP address, and they do not establish device coordinates. A site may choose its language, prices, or content using server-side IP checks, account settings, cookies, URL parameters, or its own geolocation logic. Test those behaviors independently if they matter to the screenshot.

Viewport and device emulation are also independent. Set them separately if responsive layout is part of the capture requirement; do not expect en-IN or Asia/Kolkata to choose a phone-sized viewport.

7. Common errors and fixes

Symptom Likely cause Fix
page.emulateLocale is not a function The installed Puppeteer version does not expose the method as expected, or the code is using a different package/runtime than intended. Check the installed dependency and its API documentation. Upgrade or align the code with the version your project actually runs.
Invalid timezone or an emulation failure The timezone identifier is misspelled or unsupported by the runtime. Use the IANA-style identifier Asia/Kolkata, check the error and runtime support, and await the call before navigation.
The browser reports the right values, but the page still shows another region The site may use server-side localization, a stored preference, a fixed format, or an application-level setting. Inspect the page’s own locale controls, URL, cookies, account state, and server response. Browser emulation alone does not control these inputs.
The screenshot shows a loading state or missing data The capture ran before client-side content was ready, or the selected network-idle condition never matched the page’s behavior. Wait for a content-specific selector or other deterministic ready condition, then capture.
The screenshot is unexpectedly tall or clipped fullPage controls capture extent, and fixed or dynamically expanding page elements can affect the result. Choose viewport or full-page capture deliberately and inspect the page after its content has settled.
Output differs between local and deployed runs The Puppeteer version, browser build, runtime data, fonts, or page state may differ. Align dependency and browser versions where possible, log the resolved locale/timezone, and compare the rendered page and screenshot in the deployment environment.

8. Performance, reliability, and cost

Locale and timezone emulation are two awaited setup calls; the page load and readiness condition are usually the parts that determine how long a capture takes. Keep waits bounded, use a selector tied to the required content when network idleness is unreliable, and close the browser in a finally block so failures do not leave it running.

For repeatable output, record the Puppeteer version, use explicit locale and timezone values, control relevant page state, and verify the result in the runtime that produces the screenshot. This guide does not establish a benchmark or a fixed capture cost: runtime and site behavior vary.

9. Or skip the browser setup

If you need screenshots without maintaining Puppeteer and browser setup, ScreenshotNeo is a website screenshot API and MCP server for developers. Its API supports timezone and geolocation settings among its capture options; use the ScreenshotNeo documentation to configure a capture. A basic one-call request looks like this:

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

ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for free and get 1,000 screenshots a month with no card.

10. FAQ

Should I use en-IN or hi-IN?

Use en-IN for English-language India regional behavior. Choose another supported locale when the page should render a different language or regional convention, and verify the result in your runtime.

Does setting Asia/Kolkata change the server’s clock?

No. It configures browser timezone emulation for the page. It does not change the server’s clock or prove where the browser is physically located.

Do I need fullPage: true for Indian formatting?

No. That option controls screenshot extent. Locale and timezone are configured separately before the page is captured.

Can I set locale after the page loads?

The emulation methods can be called on a page, but for predictable initial rendering, set and await both values before navigation. If you change settings later, verify that the page updates as required before capturing.

Primary references