ScreenshotNeo

BlogHow-to

How to Capture Website Screenshots from Other Countries

Learn how to capture localized website screenshots with Playwright, regional services, and ScreenshotNeo while separating IP, locale, timezone, and geolocation signals.

By the ScreenshotNeo team29 September 202610 min read

How to Capture Website Screenshots from Other Countries

To capture a website as visitors in another country see it, first identify which location signal changes the page. A site can vary its response based on the request’s public IP address, browser-reported HTML geolocation, language and locale, timezone, or a combination. Changing browser coordinates does not make your public IP appear to be in that country.

Use Playwright when you need repeatable browser-side settings such as locale, timezone, user agent, and HTML5 geolocation. Use a regional network or a screenshot provider with country routing when the site makes decisions from the request’s network location. If you are evaluating an unknown site, capture the page several times while changing one signal at a time and record the result.

Choose the location signal before you choose a tool

“From Germany” can mean several different things in a test plan. These controls are independent:

A country-specific result can depend on several independent location signals.
A country-specific result can depend on several independent location signals.
Signal What it changes What it does not prove
Public IP or regional network route The network origin visible to the target server and services that geolocate IP addresses. It does not automatically set browser language, timezone, or HTML geolocation.
HTML5 geolocation Coordinates returned to page JavaScript after the browser grants permission. It does not change the public IP address.
Locale and language Browser preferences such as Accept-Language, number formatting, and translated content. It does not guarantee country-specific prices or inventory.
Timezone JavaScript date and time behavior and time-based page variants. It does not establish a regional network origin.
User agent and viewport Device and browser presentation, responsive breakpoints, and sometimes server-side variants. It does not emulate a country’s network.

When the mechanism is unknown, make a baseline capture, then vary only one setting per run. A page that changes when you set timezoneId is responding to browser time. A page that changes only through a regional network route is using IP or another network property. Keep the evidence for every run: target URL, capture time, browser version, operating system, viewport, locale, timezone, coordinates, permission state, and network route.

Method 1: Playwright with browser-side country settings

Playwright can emulate locale, timezone, user agent, viewport, and HTML5 geolocation. Its geolocation workflow requires both coordinates and permission. The settings affect what the page receives from the browser; they do not relocate your machine’s public IP. See the Playwright emulation documentation and the screenshot documentation.

1. Install the browser and package

mkdir country-shot
cd country-shot
npm init -y
npm install playwright
npx playwright install chromium

2. Capture a page with locale, timezone, and geolocation

This complete Node.js script grants location permission, waits for a page-specific selector, and writes a full-page PNG. Replace the URL, coordinates, and selector with the values for your test.

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ headless: true });
  const context = await browser.newContext({
    locale: 'de-DE',
    timezoneId: 'Europe/Berlin',
    geolocation: { latitude: 52.5200, longitude: 13.4050 },
    permissions: ['geolocation'],
    userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/131 Safari/537.36',
    viewport: { width: 1440, height: 1000 },
    colorScheme: 'light',
    deviceScaleFactor: 1
  });

  const page = await context.newPage();
  await page.goto('https://example.com', { waitUntil: 'domcontentloaded', timeout: 60000 });

  // Wait for the content that proves the localized state is ready.
  await page.locator('main').waitFor({ state: 'visible', timeout: 30000 });
  await page.screenshot({ path: 'germany.png', fullPage: true });

  await browser.close();
})();

Use coordinates appropriate for the region you are modeling. Grant permission before navigation if the page requests geolocation during its initial load. If the page asks the user to choose a country, automate that interaction explicitly and record it as part of the setup.

3. Capture a stable viewport or one element

// Viewport only
await page.screenshot({ path: 'viewport.png', fullPage: false });

// One element, after it is visible
await page.locator('[data-testid="pricing"]').screenshot({ path: 'pricing.png' });

Full-page screenshots include content below the fold, but very long pages can be slower and may expose sticky elements repeatedly depending on the browser. Element screenshots are useful when comparing a localized banner, price card, or checkout module.

4. Wait for client-side localization

Navigation completion does not guarantee that JavaScript has rendered the country-specific content. Prefer a condition that represents the state you need:

await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
await page.waitForLoadState('networkidle');
await page.locator('[data-country="de"]').waitFor({ state: 'visible', timeout: 30000 });
await page.screenshot({ path: 'localized.png', fullPage: true });

networkidle can be a poor fit for pages with analytics, polling, or streaming requests. In those cases, wait for a stable selector or use a short, documented delay only after the page’s readiness condition.

Python Playwright example

Install the Python package and browser:

python -m pip install playwright
python -m playwright install chromium
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    context = browser.new_context(
        locale='fr-FR',
        timezone_id='Europe/Paris',
        geolocation={'latitude': 48.8566, 'longitude': 2.3522},
        permissions=['geolocation'],
        viewport={'width': 1365, 'height': 900},
    )
    page = context.new_page()
    page.goto('https://example.com', wait_until='domcontentloaded', timeout=60000)
    page.locator('main').wait_for(state='visible', timeout=30000)
    page.screenshot(path='france.png', full_page=True)
    browser.close()

The same distinction applies in Python: these settings change browser-visible values, not the network’s public IP.

Method 2: Use a country-selectable or regional capture service

A hosted browser is useful when your test needs a regional network origin, scheduled captures, or a central worker instead of a local browser. Verify exactly what “country” controls before relying on the output. Confirm the supported countries, city coverage, routing behavior, browser version, authentication support, and current commercial terms with the provider.

ScreenshotCenter’s documentation includes a country field in a screenshot request and an example that interacts with a page before capturing an element. Treat that as evidence that a country-selectable option exists in the example, not as proof of a complete country list or a particular IP-routing guarantee.

Cloudflare Browser Run documents hosted screenshot inputs, viewport and selector capture, full-page screenshots, and waiting for JavaScript-heavy pages. Its configurable user agent is a browser header setting and is not documented as a way to bypass bot protection. CloudBrowser documents geographically distributed regional API endpoints and separately documents custom latitude and longitude values reported through HTML5 geolocation. A regional endpoint and a browser coordinate are separate controls.

Hosted-capture checklist

  1. Confirm that the required country is available and determine whether routing changes public IP, browser geolocation, or both.
  2. Set viewport, locale, timezone, and user agent independently when the page depends on more than IP.
  3. Use a readiness selector or a documented wait condition for client-rendered content.
  4. Test authenticated flows and consent state separately; a regional service may start with a clean browser profile.
  5. Save the provider, region, browser version, request time, and all location settings alongside each image.

cURL and HTTP request patterns

When a provider exposes an HTTP endpoint, keep the request reproducible. A generic pattern is:

curl -G 'https://provider.example/screenshot' \
  --data-urlencode 'url=https://example.com' \
  --data-urlencode 'country=DE' \
  --data-urlencode 'viewport=1440x1000' \
  -o germany.png

Do not copy this endpoint into production without checking the provider’s current API documentation. Country codes, authentication, output formats, and waiting parameters vary.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. It supports viewport, full-page, element, locale-related browser settings, timezone, geolocation, custom headers and cookies, waits, custom JavaScript and CSS, blocking rules, caching, PDFs, bulk capture, and signed links. For a country test, set the browser-side options your page needs and use a regional route only when the target depends on public IP; confirm the required signal before interpreting the result.

Consent banners and overlays can change what a regional screenshot contains.
Consent banners and overlays can change what a regional screenshot contains.

Before each capture, ScreenshotNeo can accept consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed as clean shots, and the response reports the page verdict and billing status in X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

Read the ScreenshotNeo API documentation for all options. A minimal request is:

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(`HTTP ${res.status}`);
const fs = require('node:fs');
fs.writeFileSync('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo’s free plan includes 1,000 shots each month with no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free. Create a free ScreenshotNeo account and start with the no-card plan.

Relevant capture options

Requirement Playwright setting or workflow Hosted API consideration
IP-based localization Use a regional network outside Playwright. Confirm country routing and what network the target sees.
HTML geolocation geolocation plus permissions: ['geolocation']. Check whether coordinates are supported independently of network region.
Language locale; verify rendered text and request headers. Set locale or custom headers if supported.
Time-based content timezoneId. Set timezone separately from country.
Responsive layout viewport and deviceScaleFactor. Use explicit viewport and retina scale.
Dynamic content Selector wait, network idle, or a controlled delay. Use provider wait conditions and page-state controls.
Authenticated page Context storage, cookies, headers, or login flow. Confirm cookie, header, and authorization support.
One component locator.screenshot(). Use a CSS selector capture option.

Troubleshooting

The page still shows the default country

Cause: The site is using public IP, a cookie, account settings, or server-side negotiation rather than browser geolocation. Fix: inspect redirects and response behavior, clear the context, change one signal at a time, and use a verified regional network route when the server requires it.

Geolocation permission is denied

Cause: Coordinates were supplied without granting permission, or the page requests permission from a different origin. Fix: add the exact origin to the browser context permissions and set coordinates before navigation.

The screenshot contains an English page but a local currency

Cause: Different systems are controlling language and pricing. Fix: test locale, IP, cookies, and account state separately; document which combination produced the result.

Localized content is missing from the image

Cause: Capture occurred before client-side rendering completed. Fix: wait for a selector that proves the desired state, then capture. Avoid relying only on a fixed delay.

The page is blocked or shows a CAPTCHA

Cause: Bot detection, rate limits, or an unsupported network. Fix: reduce concurrency, use a permitted route, preserve a normal browser profile, and follow the site’s access rules. A changed user agent alone is not a bot-protection bypass.

Full-page output is unexpectedly tall or clipped

Cause: Infinite scroll, sticky elements, or content that loads only after scrolling. Fix: capture a defined element or viewport, scroll deliberately to trigger lazy content, and wait for the final height before taking the image.

Two captures differ even with identical settings

Cause: Browser version, operating system, fonts, hardware, headless mode, animations, ads, or changing remote content differ. Fix: pin the browser and viewport, disable animations where appropriate, wait for stable content, and run both baseline and comparison captures in the same environment. Playwright notes that rendering varies across host and browser conditions.

Performance, reliability, and cost

  • Make the smallest capture: element or viewport screenshots use less time and storage than full-page images.
  • Wait with intent: selector-based readiness is usually more reliable than long arbitrary sleeps; network idle can never arrive on pages with continuous requests.
  • Control concurrency: parallel browser contexts improve throughput until CPU, memory, bandwidth, or the target’s rate limits become the bottleneck.
  • Reuse browser infrastructure: keep a browser process alive while creating isolated contexts for each test, and close contexts after capture.
  • Cache deliberately: cache only when a stale image is acceptable. Record the URL, settings, and capture timestamp with every artifact.
  • Compare like with like: fix browser version, viewport, scale, fonts, timezone, locale, and route before interpreting pixel differences.
  • Budget for failed pages: with ScreenshotNeo, clean shots are billed while bot checks, blank pages, timeouts, failed loads, and cache hits are not; inspect the verdict and billing headers in your pipeline.
  1. Write down the question: IP localization, geolocation behavior, translated content, timezone behavior, or a combined visitor experience.
  2. Capture a baseline with a fresh context and a fixed viewport.
  3. Change one signal and capture again. Repeat for IP route, locale, timezone, and coordinates.
  4. Wait for a reliable selector and save HTML or metadata that explains the visible variant.
  5. Run each condition more than once when the page contains ads, experiments, or rotating content.
  6. Store the image with all settings and the response status so another developer can reproduce it.
  7. Automate the stable case in Playwright or move it to a hosted API once the required location signal is confirmed.

FAQ

Can browser geolocation make my request originate from another country?

No. It changes coordinates reported to page JavaScript after permission is granted. A regional network route is required for IP-based localization.

Should I set locale and timezone when testing an IP location?

Usually yes. Real visitors often present several correlated signals, and testing them independently helps you discover which one the site uses.

Is a country parameter the same as a local IP?

Not necessarily. Confirm what the provider’s country control changes and test the target’s observed behavior before treating it as an IP-location guarantee.

What should I record for an audit?

Record URL, timestamp, browser and operating system, viewport, scale, locale, timezone, coordinates, permission state, cookies, user agent, network region, wait condition, and output hash.

When is a screenshot API better than local Playwright?

Use an API when you need a shared service, signed links, asynchronous jobs, bulk URLs, PDFs, usage reporting, or an MCP workflow. Use local Playwright when you need maximum control over the browser and network environment.