ScreenshotNeo

BlogHow-to

How to Compare Screenshots of an Indian Web Page in Hindi and English

Capture Hindi and English pages in the same browser conditions, compare approved locale baselines or aligned screenshots, and review Devanagari rendering without mistaking valid text reflow for a defect.

By the ScreenshotNeo team4 October 202610 min read

To compare screenshots of an Indian webpage in Hindi and English, capture both versions at the same route, viewport, browser version, environment, scroll position, data, and UI state. Then either compare each locale against its own approved screenshot baseline to find regressions, or align the Hindi and English captures side by side to review localization. Do not expect a pixel-identical result across languages: text length and line wrapping can legitimately differ. Inspect Hindi Devanagari shaping, legibility, clipping, overlap, and content separately; a visual diff cannot establish that a translation is correct.

1. Choose what the comparison should answer

There are two useful comparison modes, and they answer different questions:

  • Locale regression: Does the current Hindi page still match the approved Hindi design, and does the current English page still match the approved English design? Keep separate baselines for each locale. This is the right mode for automated visual regression checks.
  • Localization review: How does the Hindi page differ from its English counterpart, and are both usable and consistent with the intended design? Capture both pages under matching conditions, then review them side by side or with an aligned image diff. Differences in text and wrapping are expected; investigate whether they cause usability or layout problems.

Do not use an English baseline as the expected pixel output for Hindi. The languages use different glyphs and may need different line breaks, heights, and spacing. A useful review can still compare shared structure such as navigation, hierarchy, imagery, button placement, and page completeness.

2. Make the captures comparable

Before comparing pixels, control the inputs that affect rendering. Use the same:

  • Page route and equivalent content or test data.
  • Viewport width and height, device scale factor, browser, browser version, and operating-system or container image.
  • Scroll position and page state, including open menus, selected tabs, consent state, and authentication state.
  • Font availability and loading state. Wait for web fonts and page content before taking the capture.
  • Animation state. Disable or settle animations, carousels, clocks, rotating banners, and other transient content.

Playwright cautions that rendering can vary with the host OS, browser version and settings, hardware, power source, and headless mode. Generate and compare baselines in the same environment where possible; maintain separate baselines for browser/platform combinations that intentionally differ. See the Playwright visual comparisons documentation.

Set the document language correctly: use lang="hi" for Hindi content and lang="en" for English content, with language metadata on individual regions when a page mixes languages. W3C explains that language information helps user agents process content, and that CSS :lang() can apply language-specific presentation such as font choices. Metadata supports appropriate rendering; it does not verify translation accuracy. See W3C language declarations and the CSS :lang() selector.

3. Capture locale baselines with Playwright

The example below is a runnable Playwright Test pattern for a site whose locale is selected by route. Change the two URLs, selectors, and viewport to match the site. The first run creates screenshot baselines; subsequent runs compare against them. The expected snapshots are separate for Hindi and English.

// tests/locales.visual.spec.ts
import { test, expect } from '@playwright/test';

test.use({
  viewport: { width: 1365, height: 900 },
  deviceScaleFactor: 1,
  colorScheme: 'light',
  locale: 'en-US', // Browser locale is held constant; the URL selects page language.
});

for (const locale of [
  { name: 'en', url: 'https://example.com/en/products' },
  { name: 'hi', url: 'https://example.com/hi/products' },
]) {
  test(`approved visual baseline: ${locale.name}`, async ({ page }) => {
    await page.goto(locale.url, { waitUntil: 'networkidle' });
    await page.evaluate(() => document.fonts.ready);
    await page.locator('main').waitFor({ state: 'visible' });

    // Stabilize common sources of nondeterminism. Prefer app-specific test controls
    // for carousels, timestamps, randomized content, and animations where available.
    await page.addStyleTag({ content: `
      *, *::before, *::after {
        animation: none !important;
        transition: none !important;
        caret-color: transparent !important;
      }
    ` });

    await expect(page).toHaveScreenshot(`products-${locale.name}.png`, {
      fullPage: true,
      animations: 'disabled',
      maxDiffPixels: 100,
    });
  });
}

Install Playwright Test in the project with npm init playwright@latest if it is not already present, save the test in the configured test directory, and run npx playwright test. The first execution writes reference snapshots; inspect and commit the approved files. Later executions report mismatches and produce actual/diff output for review. When intentionally approving a visual update, review the changed capture first, then update snapshots with npx playwright test --update-snapshots.

maxDiffPixels is a tolerance policy, not a way to make a bad match good. Start with a strict setting appropriate to the stable test environment, inspect the diff, and adjust only when the remaining variation is understood. Playwright also supports screenshot settings such as threshold, maxDiffPixelRatio, masks, and animation handling. Consult the API reference for the current options. A masked region should be limited to content that is intentionally variable; masking large text or layout regions can hide real defects.

4. Capture Hindi and English for a localization review

For an intentional cross-language review, capture both pages with identical browser conditions and comparable state, then place them side by side. Playwright can save full-page captures directly. This standalone Node.js script uses Playwright and writes two PNG files for manual review; it is not a pixel-baseline test.

// compare-locales.mjs
import { chromium } from 'playwright';

const pages = [
  ['english.png', 'https://example.com/en/products'],
  ['hindi.png', 'https://example.com/hi/products'],
];

const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
  viewport: { width: 1365, height: 900 },
  deviceScaleFactor: 1,
  locale: 'en-US',
  colorScheme: 'light',
});

try {
  for (const [file, url] of pages) {
    const page = await context.newPage();
    await page.goto(url, { waitUntil: 'networkidle' });
    await page.evaluate(() => document.fonts.ready);
    await page.locator('main').waitFor({ state: 'visible' });
    await page.addStyleTag({ content: `
      *, *::before, *::after {
        animation: none !important;
        transition: none !important;
        caret-color: transparent !important;
      }
    ` });
    await page.screenshot({ path: file, fullPage: true, animations: 'disabled' });
    await page.close();
  }
} finally {
  await context.close();
  await browser.close();
}

Install the browser library with npm install -D playwright, install its browser with npx playwright install chromium, and run node compare-locales.mjs. A side-by-side image viewer is often enough for a human review. If using an image-diff tool, align captures to the same width and page landmarks first; vertical shifts caused by longer Hindi text can otherwise make every section below the shift appear different.

5. Review the Hindi and English results systematically

Review content and rendering as separate checks. For the images, use this checklist:

  1. Confirm page completeness. Verify both captures show the intended route, expected content, loaded images, and correct locale. Check that a fallback or untranslated string has not appeared.
  2. Inspect Devanagari text closely. Look for missing glyph boxes, malformed conjuncts or matras, awkward positioning, clipped ascenders or descenders, and text that is too small or crowded to read. W3C’s material on Devanagari layout and text covers script shaping and positioning considerations.
  3. Check line wrapping and expansion. Hindi may occupy a different number of lines than English. Confirm that headings, cards, navigation, buttons, and form labels still fit and remain understandable. A changed line break alone is not necessarily a defect.
  4. Check clipping and collisions. Inspect containers, fixed-height components, overlays, buttons, menus, and form controls for text overflow, overlap, hidden content, or unreachable actions.
  5. Compare shared visual intent. Check information hierarchy, order of sections, images, color, navigation, spacing rhythm, and action prominence. Where page height changes, compare corresponding landmarks rather than treating a vertical offset as a global regression.
  6. Verify the words separately. Have the displayed Hindi and English content checked for meaning, completeness, and intended wording. Pixel comparison can show that text differs, but cannot tell whether a translation is accurate.

W3C’s Devanagari Layout Requirements provides script-specific context for glyph shaping and positioning. Use the actual supported browsers and fonts for the site: the sources do not certify any particular page’s font choice or translation.

6. Optional command-line image diff

For quick manual review outside the browser test runner, ImageMagick can create a visual difference image from two same-sized captures. Install ImageMagick for your operating system, then run:

magick compare -metric AE english.png hindi.png locale-diff.png

The command reports an absolute pixel difference and writes a diff image. This number is not a localization quality score: because the text is in different languages, many differing pixels are expected. The captures must have matching dimensions for a direct comparison. For differing page heights, compare aligned sections or use separate locale baselines instead of resizing one image indiscriminately, which can distort glyphs.

7. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. A single GET request can capture a URL as an image or PDF. For repeatable locale captures, request each locale URL with the same viewport and output settings, then review the resulting images or compare each locale with its approved reference. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://example.com/hi/products \
  -o hindi.webp

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://example.com/en/products \
  -o english.webp

Python equivalent:

import requests

for language, url in [
    ("hi", "https://example.com/hi/products"),
    ("en", "https://example.com/en/products"),
]:
    response = requests.get(
        "https://api.screenshotneo.com/v1/shot",
        params={"access_key": "YOUR_API_KEY", "url": url},
        timeout=90,
    )
    response.raise_for_status()
    with open(f"{language}.webp", "wb") as image:
        image.write(response.content)

Node.js equivalent:

for (const [language, url] of [
  ['hi', 'https://example.com/hi/products'],
  ['en', 'https://example.com/en/products'],
]) {
  const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url });
  const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
  if (!res.ok) throw new Error(`${language} capture failed: ${res.status}`);
  const image = Buffer.from(await res.arrayBuffer());
  await import('node:fs/promises').then(fs => fs.writeFile(`${language}.webp`, image));
}

ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks, blank pages, failed loads, timeouts, 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 PDFs. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Get started with 1,000 free screenshots a month, no card required.

8. Troubleshooting

Symptom Likely cause What to do
Large diffs on every run Captures are produced in different browser, OS, font, or headless environments, or dynamic content is changing. Pin the browser and execution environment; stabilize timestamps, randomized content, animations, and data; generate and compare snapshots in that same environment.
Hindi characters show as boxes or are cut off The required glyphs may be missing from the active font, the font may not have loaded, or the component clips the shaped text. Wait for document.fonts.ready, confirm an appropriate Devanagari-capable font is available, and inspect the relevant container’s height, overflow, and line height in the target browser.
Hindi page is much taller and the diff is mostly red Different text lengths and line breaks move content below the changed area. Use independent approved baselines for regression. For localization review, align equivalent section landmarks and judge usability and hierarchy instead of requiring pixel identity.
Snapshot fails before comparison The page, target element, or fonts have not finished loading, or the route redirects to a different state. Wait for a stable application-specific readiness condition and the main content; verify the final URL and state. Use network idle only when the page actually becomes idle, since persistent connections can prevent it.
Diff changes between local and CI Browser binaries, OS packages, fonts, device scale, or rendering mode differ. Run the same browser and container image used to create the baseline, or maintain separate platform baselines where the difference is intentional.
Diff image is misaligned or command fails Full-page captures have different heights or dimensions. Compare matching viewport captures or crop corresponding sections to a common size. Do not stretch the image to force alignment.
Snapshot update hides a real issue A baseline was accepted without inspecting the actual and diff images. Review the proposed image change and approve only intentional design or content changes. Keep locale snapshots separate.
Translation seems wrong but visual diff looks small Pixel similarity does not measure meaning; a short incorrect phrase can have few changed pixels. Review the displayed strings with a language reviewer or content source, separately from the visual regression result.

9. Performance, reliability, and cost

Browser captures take time because the browser must navigate, load content and fonts, reach a stable state, and render the screenshot. Full-page images consume more memory and comparison work than viewport shots. Keep the test viewport and target pages focused, avoid waiting on irrelevant persistent network activity, and use a deterministic readiness signal where the application provides one. Parallel capture can reduce wall time but increases browser resource use; choose concurrency based on the capacity of the CI runner.

For reliable visual regression, pin the browser and host environment, keep reviewed baselines under version control, and make baseline updates deliberate. Use strict visual tolerances first, then tune them only after examining recurring environment noise. Separate Hindi and English baselines so legitimate language differences do not become permanent false alarms.

With a local Playwright workflow, the practical cost is the compute time and maintenance of the browser environment and snapshots. ScreenshotNeo offers a free allowance of 1,000 shots monthly without a card. Paid plans are 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; annual billing gives two months free. Every feature is available on every plan. Choose based on capture volume and whether a managed API or MCP workflow is useful; compare the returned image and the page-verdict/billing headers as part of your own process.

10. Frequently asked questions

Should I compare Hindi screenshots directly with English screenshots in CI?

Usually no. Keep one approved baseline per locale for regression checks. Compare Hindi with English directly when reviewing localization, and treat the result as a usability and design review rather than a pixel-equality test.

Does a screenshot diff confirm the Hindi translation is correct?

No. It identifies visual changes. Translation meaning, completeness, and language quality need a separate content review.

Should the HTML language attribute change with the selected locale?

Yes. Declare the language of the page or content region with the appropriate lang value so browsers and assistive technologies can handle it appropriately. It does not substitute for checking the rendered text and layout.

Why do screenshots differ across machines if the page code is unchanged?

Browser and operating-system versions, fonts, hardware, settings, and headless rendering can affect output. Keep baseline generation and comparison in a consistent environment.