How to Use Apify to Screenshot Websites in Different Languages
Set a screenshot Actor’s language preference, add a country proxy only when needed, and retrieve the resulting image through Apify’s API.
To screenshot a localized page with Apify, choose a screenshot Actor whose input schema supports language settings, then set its documented language field. For Apify’s Website Screenshot and PDF Actor, send an Accept-Language header, such as de-DE. Another Actor, Website Screenshot API — Full Page, PDF, No Cookie Banners, accepts a browser locale field. Use a country-targeted proxy only if the site also selects content based on visitor IP location. Neither setting guarantees that a site has a translation or will show it.
The exact inputs, limits, output format, and pricing differ by Actor. Check its current Store page and input schema before running it. The examples below use the reestri/web-screenshot Actor and its documented urls, format, fullPage, and headers fields.
1. Choose an Actor and the right localization signal
Start with the target page and how it decides what language to show. A language preference tells the browser or request which language is preferred. A proxy changes the network route and can give the site a different apparent visitor location. These are distinct signals.
| What you need | What to configure | What to check |
|---|---|---|
| Preferred page language | The selected Actor’s documented Accept-Language header or browser locale |
That the Actor supports the field and the site responds to it |
| Country-specific version | An Actor with proxy support and a proxy country, if available | Whether the Actor uses Apify Proxy or another proxy, its cost, and country availability |
| A specific translated page | The localized URL, such as a language path or subdomain | Whether the URL itself selects the desired version |
For the reestri/web-screenshot Actor, the documented language mechanism is an Accept-Language header. It does not rotate proxies, accept cookies, log in, or solve captchas. For an Actor with a locale input and optional proxy configuration, use those exact fields from its schema; do not assume every Actor accepts the same JSON.
2. Capture a localized page in the Apify Console
- Open the selected Actor’s Apify Store page and inspect its input schema. Confirm language support, proxy support if needed, capture controls, and output retrieval steps.
- Enter the complete page URL. If the site has a known language-specific path or subdomain, use it directly.
- Set the documented language preference. For the Website Screenshot and PDF Actor, use an
Accept-Languageheader. Its documented German example usesde-DE. - Choose viewport or full-page capture. Use full-page for the entire scrollable page; use viewport when you only need the initial visible screen.
- Set waits based on the page. A selector wait is useful when a particular translated component must appear. Network-idle waiting can help with dynamic content but can take longer.
- Run the Actor and inspect its output record and file link. Confirm the screenshot actually shows the expected language and that the page did not return an error or block screen.
Example input for the reestri/web-screenshot Actor:
{
"urls": ["https://example.com"],
"format": "png",
"fullPage": true,
"headers": {
"Accept-Language": "de-DE"
}
}
This is an input example, not a guarantee that example.com serves German. The Actor’s output includes file information; consult its current output schema for the file URL and capture status.
3. Run the Actor through Apify’s API
You need an Apify account and API token. The following runnable examples submit the same input to the synchronous run-and-return-dataset-items endpoint. Set APIFY_TOKEN in your environment first. The returned data describes the run’s dataset items; use the selected Actor’s documented output to retrieve the actual image file. The Actor page explains that its files are stored in the run’s default key-value store and its dataset contains file links.
cURL
export APIFY_TOKEN='YOUR_APIFY_API_TOKEN'
curl --fail-with-body \
-X POST \
"https://api.apify.com/v2/acts/reestri~web-screenshot/run-sync-get-dataset-items?token=${APIFY_TOKEN}" \
-H 'Content-Type: application/json' \
-d '{
"urls": ["https://example.com"],
"format": "png",
"fullPage": true,
"headers": {"Accept-Language": "de-DE"}
}'
Python
import os
import requests
api_token = os.environ["APIFY_TOKEN"]
endpoint = (
"https://api.apify.com/v2/acts/reestri~web-screenshot/"
"run-sync-get-dataset-items"
)
payload = {
"urls": ["https://example.com"],
"format": "png",
"fullPage": True,
"headers": {"Accept-Language": "de-DE"},
}
response = requests.post(
endpoint,
params={"token": api_token},
json=payload,
timeout=300,
)
response.raise_for_status()
items = response.json()
print(items)
Install the dependency with python -m pip install requests. The synchronous request can take time; choose a client timeout appropriate for the Actor’s configured per-page timeout and number of URLs.
Node.js
const apiToken = process.env.APIFY_TOKEN;
if (!apiToken) throw new Error('Set APIFY_TOKEN first');
const endpoint = new URL(
'https://api.apify.com/v2/acts/reestri~web-screenshot/run-sync-get-dataset-items'
);
endpoint.searchParams.set('token', apiToken);
const response = await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
urls: ['https://example.com'],
format: 'png',
fullPage: true,
headers: { 'Accept-Language': 'de-DE' },
}),
signal: AbortSignal.timeout(300_000),
});
if (!response.ok) {
throw new Error(`Apify returned ${response.status}: ${await response.text()}`);
}
console.log(await response.json());
Node.js versions with built-in fetch can run this as an ES module. For larger jobs, use Apify’s asynchronous run endpoint, retain the run ID, wait for completion, and fetch the dataset or key-value-store file using the API. The asynchronous path avoids holding a synchronous request open for a long batch.
4. Decide whether to use a country proxy
Try the language preference first when the website is expected to negotiate language from the request. Add geographic targeting when the site appears to choose a version from IP location—for example, when the same language setting still lands on a country-specific storefront.
Choose an Actor that explicitly supports proxy configuration and follow its input schema. Apify Proxy accepts country targeting where available; its documentation notes that a connection fails if no proxy servers are available for the requested country. Proxy sessions can be used to reuse the same IP for multiple connections. Check the Actor’s instructions and Apify’s current Proxy documentation for supported configuration and account requirements.
- Do not add a proxy automatically: it may add cost and complexity without changing the page.
- A proxy does not set the page language by itself. Keep the language header or locale when both signals matter.
- Proxy location may still lose to the URL, a saved site preference, account settings, or other site logic.
- Availability can vary by country; handle a proxy connection error as a configuration or availability issue rather than proof that the page lacks a translation.
5. Tune the capture for complete, useful results
Localization is only one part of a reliable screenshot. Actor-specific controls determine which part of the page is captured and whether late content has loaded.
| Setting | When to use it | Trade-off or caveat |
|---|---|---|
| Full-page vs viewport | Full-page for a page archive; viewport for a first-screen check | Very long pages can hit Actor-specific height or timeout limits. The reestri/web-screenshot Actor documents a configurable maximum height and marks truncation. |
| Wait for page load | Default for typical static pages | A page may signal load before a client-rendered translation appears. |
| Wait for selector | When a translated heading, menu, or result is the required evidence | Use a selector that exists in the target language/version; a missing selector can consume the timeout. |
| Network idle or delay | When content arrives after initial navigation or needs time to settle | Network idle is slower and can be unsuitable for pages with continuous requests. Extra delays increase run time. |
| Scroll to load lazy images | Long pages with images loaded as the page scrolls | Supported option and behavior vary by Actor. |
| Multiple URLs | Comparing locale variants or processing a small set of pages | Check per-run limits, concurrency, and how each Actor reports individual failures. |
When comparing languages, keep the viewport, capture mode, wait condition, and other settings constant. Otherwise, a difference in the image may come from capture configuration instead of localization.
6. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Screenshot stays in the original language | The site ignores the language preference, does not offer that translation, or prioritizes its URL, cookies, account, or location rules. | Verify the Actor accepted the documented field; try the site’s known localized URL; check a country proxy only if evidence suggests IP-based selection. |
| Actor rejects an input field | The field belongs to a different Actor or has a different name/type in this Actor. | Compare every input against that Actor’s current schema. Do not copy locale into an Actor that documents headers, or vice versa. |
| Proxy connection fails | The country may have no available proxy servers, proxy configuration may be unsupported, or the account may not meet the Actor’s requirements. | Check the proxy country and Actor documentation. Retry without geographic targeting to determine whether the proxy is the failure source. |
| Screenshot is a CAPTCHA, block page, or error | The website blocks automated browsers or returned an HTTP error. The reestri/web-screenshot Actor captures as an anonymous visitor and does not solve captchas or change identity. |
Inspect status and page output; confirm the URL is publicly accessible. Do not assume a language header bypasses access controls. |
| Translated content is missing or blank | Client-side rendering has not finished, a selector wait did not match, or the target translation is unavailable. | Use a relevant selector or modest delay, then inspect the resulting page and status. Avoid indefinite waits. |
| Long page is cut off | Actor height cap or timeout. | Check the Actor’s maximum height and truncation signal; increase supported limits or split the task if the Actor allows it. |
| API call times out | Large pages, slow resources, long waits, or multiple URLs exceed the client’s synchronous timeout. | Reduce batch size, use an appropriate client timeout, or switch to an asynchronous run and poll for completion. |
| API returns authorization or validation errors | Missing/invalid token, wrong Actor identifier, malformed JSON, or invalid URL. | Confirm the token is present, the Actor ID is correct, the JSON matches its schema, and URLs use public HTTP or HTTPS pages. |
| API response has data but no image bytes | The endpoint returns dataset items and file metadata rather than an image binary response. | Use the output’s file key or signed fileUrl and the Actor’s documented file retrieval flow. |
7. Performance, reliability, and cost
Runtime depends on page response time, capture mode, wait strategy, page length, and batch concurrency. Full-page captures and network-idle waits can take longer than a viewport capture after normal page load. For repeatable comparisons, choose stable wait criteria and keep capture settings consistent.
Inspect each URL’s status and file output rather than treating a completed Actor run as proof that every page produced the expected screenshot. The reestri/web-screenshot documentation says dropped connections and browser crashes are retried once by default, while timeouts are not retried. Other Actors can have different retry and failure behavior.
Actor prices and Apify platform costs depend on the selected Actor and current plan. Check the Store pricing and platform pricing before running a large batch, and account for storage and proxy usage where applicable. The research sources do not establish one price that applies across screenshot Actors.
8. Or skip the browser setup
With ScreenshotNeo, send one GET request with the URL to receive a PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API docs for capture options.
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}`);
- Cookie banners, popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
- Bot checks, blank pages, failed loads, timeouts, and cache hits cost nothing. Responses identify the page verdict and billing status in headers.
- An MCP server provides
take_screenshot,get_page_info, andcapture_pdftools for Claude, Cursor, and other MCP clients. - The free plan includes 1,000 screenshots a month with no card. Paid plans start at $5 for 3,000 screenshots.
Sign up for 1,000 free screenshots a month, no card required.
9. FAQ
Does setting a language guarantee a translated screenshot?
No. It requests or emulates a language preference. The site must provide and select that language for the setting to affect the page.
Should I use a proxy for every localized screenshot?
No. Use one when the site’s behavior indicates that visitor IP location affects the version. A language header or locale is the direct setting for language preference.
Can an Apify screenshot Actor capture a page behind login?
It depends on the Actor. The reestri/web-screenshot Actor documents anonymous visitor captures and does not log in. Check another Actor’s authentication inputs and use only credentials and access you are authorized to use.
Can I compare multiple languages in one run?
Many Actors accept multiple URLs, but language settings may apply to the whole run rather than per URL. Check the schema; separate runs are safer when each URL needs a different language header or locale.


