How to Capture a Hindi Website at the Right Size with Playwright
Set the viewport, choose viewport or full-page capture, and wait for Hindi web fonts before taking a Playwright screenshot.
To capture a Hindi website at a predictable size with Playwright, set the browser context viewport before navigation, wait for the page’s fonts to finish loading, then choose viewport, full-page, or element capture. Use scale: 'css' when you want one output image pixel per CSS pixel; use scale: 'device' for device-pixel output, which can be larger on high-DPI contexts.
The example below captures the entire scrollable page as a PNG. Remove fullPage: true to capture only the visible viewport. The official Playwright screenshot guide and Page API document these options.
1. Install Playwright and capture the page
In a new Node.js project, install Playwright and its Chromium browser:
npm install playwright
npx playwright install chromium
Save this as screenshot-hindi.js. Replace the example URL with the page you need to capture.
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
try {
const context = await browser.newContext({
viewport: { width: 1365, height: 900 },
deviceScaleFactor: 1,
});
const page = await context.newPage();
await page.goto('https://example.com/hi', { waitUntil: 'load' });
await page.evaluate(() => document.fonts.ready);
await page.screenshot({
path: 'hindi-page.png',
fullPage: true,
scale: 'css',
});
} finally {
await browser.close();
}
})();
Run it with node screenshot-hindi.js. Setting the viewport on the context before opening the page ensures the page lays out at the intended CSS width and height from its initial navigation. Awaiting document.fonts.ready lets the fonts currently used by the document finish loading before capture. It does not fix a missing or broken font.
2. Choose the capture area and output size
“Correct size” depends on what the screenshot is for. The viewport controls the page’s layout dimensions; the screenshot options control which area is captured and how CSS pixels map to output pixels.
| Goal | Setting | Result |
|---|---|---|
| Capture what is visible in the browser | Omit fullPage or set it to false |
The current viewport is captured. |
| Capture the whole scrollable page | fullPage: true |
A single tall image of the page. |
| Match CSS dimensions in image pixels | scale: 'css' |
One output pixel per CSS pixel. |
| Capture device pixels | scale: 'device' |
Uses device pixels; the result may have more pixels than the CSS dimensions. |
| Capture one element | Locator screenshot() |
The selected element is captured. |
| Capture a specific rectangular region | clip |
Captures the specified area. |
Viewport-only capture
For a viewport image at 1365 × 900 CSS pixels, omit fullPage:
await page.screenshot({
path: 'hindi-viewport.png',
scale: 'css',
});
The viewport setting is not a request to resize the final image after capture. It sets the browser’s layout viewport. A responsive site may therefore show a different layout at a different viewport width.
Full-page capture
Set fullPage: true when you need the scrollable document in one image:
await page.screenshot({
path: 'hindi-full-page.png',
fullPage: true,
scale: 'css',
});
The result can be much taller and larger in bytes than a viewport screenshot. If you need a fixed-height image, capture the viewport or a defined clip instead.
Element or clipped-region capture
Use a locator when you want a specific element. Playwright scrolls the element into view before taking its screenshot:
await page.locator('main article').screenshot({
path: 'hindi-article.png',
});
For an explicit region, pass a clip rectangle in page coordinates:
await page.screenshot({
path: 'hindi-region.png',
clip: { x: 0, y: 0, width: 900, height: 600 },
scale: 'css',
});
A clip rectangle outside the page’s usable area or with unsuitable dimensions may fail. If you are capturing a particular component, an element screenshot is often easier to maintain than hard-coded coordinates.
Output type, transparency, and buffers
The screenshot type is inferred from the filename extension when you save to a path. You can set it explicitly with type: 'png', 'jpeg', or 'webp' where supported by the installed Playwright version. JPEG and WebP support a quality value; it does not apply to PNG. For PNG transparency, use omitBackground: true.
const image = await page.screenshot({
type: 'jpeg',
quality: 85,
scale: 'css',
});
// `image` is a Buffer. Save it or pass it to another function.
require('fs').writeFileSync('hindi-page.jpg', image);
Use the Page screenshot API reference for the complete option list supported by your Playwright release, including path, type, quality, clip, full-page capture, scale, and background handling.
3. Make Hindi font rendering reliable
Wait for fonts before capturing:
await page.evaluate(() => document.fonts.ready);
MDN describes document.fonts.ready as a promise that resolves when font loading and related layout operations for the document have completed. This reduces the chance of capturing during a font-loading race. It does not guarantee that the intended font exists, loaded successfully, or contains the required glyphs. See MDN’s Document.fonts reference.
If Hindi characters look broken, unexpectedly styled, or different from the site’s normal appearance, check the page’s CSS font-family, the network result for its font requests, and whether the operating system or container running Chromium has the needed fonts available. The provided research does not establish a Hindi-specific Playwright font fix, so diagnose the actual font and environment rather than assuming a screenshot option will repair it.
4. Control layout and timing
- Set the viewport before navigation. Choose the width and height when creating the browser context. This lets responsive layout run against the intended viewport.
- Wait for the right page state.
waitUntil: 'load'waits for the load event. If the page renders important content later, wait for a meaningful locator or page-specific condition before capture. - Wait for fonts. Await
document.fonts.readyafter navigation and before the screenshot. - Choose the output scale deliberately. CSS scale is useful for predictable CSS-pixel dimensions. Device scale can produce more pixels, so account for that in storage and image processing.
- Use a stable environment for visual comparisons. Keep browser, operating system, fonts, settings, and execution mode consistent between baseline and comparison runs. Playwright notes that rendering can vary across browsers and platforms; see Visual comparisons.
For Playwright Test visual assertions, toHaveScreenshot() waits for two consecutive screenshots to match before comparing with the expected image. It is a test-runner assertion, not a replacement for saving an image from a regular Playwright script. See PageAssertions.
5. Other runnable capture options
Python
Install the Python package and browser, then use the asynchronous API:
pip install playwright
playwright install chromium
import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch()
try:
context = await browser.new_context(
viewport={"width": 1365, "height": 900},
device_scale_factor=1,
)
page = await context.new_page()
await page.goto("https://example.com/hi", wait_until="load")
await page.evaluate("() => document.fonts.ready")
await page.screenshot(
path="hindi-page.png",
full_page=True,
scale="css",
)
finally:
await browser.close()
asyncio.run(main())
cURL and Node.js with ScreenshotNeo
Playwright is useful when you need browser automation, custom interaction, or a local browser workflow. If your job is to request and save a screenshot, ScreenshotNeo provides a website screenshot API. Its API accepts a URL and returns an image or PDF. See the ScreenshotNeo API documentation for request parameters.
Or skip the browser setup
Make one request to capture a URL. Change the target URL and output extension as needed.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/hi -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com/hi"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com/hi' });
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());
require('fs').writeFileSync('shot.webp', image);
ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools for screenshots, page information, and PDF capture. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account.
6. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Image dimensions are larger than expected | scale: 'device' captures device pixels, or the page is taller than the viewport with full-page mode. |
Use scale: 'css' for one image pixel per CSS pixel. Remove fullPage: true for viewport-only output. |
| Only the top of the page appears | The default capture is the visible viewport. | Set fullPage: true to capture the scrollable page, or use a locator/clip for a specific region. |
| Hindi glyphs look wrong or a fallback font appears | The intended web font may not have loaded, may have failed, or may be unavailable in the capture environment. | Await document.fonts.ready; inspect CSS font-family and font network requests; check font availability in the browser’s operating environment. |
| Screenshot differs between machines | Browser, platform, fonts, settings, hardware, and headless mode can affect rendering. | Run baseline and comparison in the same browser and operating environment, with consistent fonts and settings. |
| Content is missing despite a successful navigation | The page may populate content after the load event. | Wait for the page-specific element or condition that indicates the desired content is ready, then await fonts and capture. |
| Capture fails for a large page or image processing is slow | A full-page screenshot can produce a very tall, high-pixel-count image. | Capture only the needed region, use CSS scale when appropriate, or split work into smaller page regions. |
7. Performance, reliability, and cost
A screenshot’s pixel count affects its memory use, encoding time, file size, and transfer time. Full-page capture and device-pixel scale can increase that count substantially. For repeatable visual work, select the smallest viewport, region, and pixel scale that satisfy the use case.
Browser automation also requires a compatible browser installation and a stable runtime environment. Reuse the same Playwright and browser versions and operating environment for visual baselines. For automated jobs, close the browser in a finally block, as in the examples, so failures do not leave the browser process running.
Playwright’s cost depends on where and how you run the browser; the supplied research does not provide pricing or performance benchmarks. ScreenshotNeo’s listed plans are Free (1,000 shots/month), Starter ($5 for 3,000), Growth ($15 for 15,000), Pro ($39 for 60,000), Scale ($99 for 250,000), and Business ($249 for 1,000,000); yearly billing gives two months free, and every feature is available on every plan. Its billing rules treat bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits as non-billable.
FAQ
Does waiting for document.fonts.ready guarantee the intended Hindi font?
No. It signals that the document’s current font loading and related layout work have completed. Check the actual font requests and CSS if the expected glyphs or typeface are missing.
Should I use CSS scale or device scale for an exact image size?
Use scale: 'css' when you want the screenshot’s image pixels to correspond one-to-one with CSS pixels. Use device scale when you need device-pixel detail and can accept a larger output.
Can I use toHaveScreenshot() in a regular Node.js script?
It is a Playwright Test assertion. For a regular script that writes an image, use page.screenshot().


