How to Fix Playwright Screenshots with Hindi Fonts on Ubuntu
Fix missing or broken Hindi text in Playwright screenshots by installing Devanagari fonts where Chromium runs, then verify the result in that runtime.
If Hindi text is missing, replaced by boxes, or rendered with an unexpected fallback in a Playwright screenshot on Ubuntu, first check whether the Linux environment running Chromium has a font with Devanagari glyph coverage. Install the font package in that environment, rebuild the container or runner if needed, and capture a page containing representative Hindi text again.
On Ubuntu 22.04 (Jammy), the fonts-deva package includes Lohit and Samyak TrueType fonts for Devanagari. Package names can differ by Ubuntu release, so verify the package for the release you actually use. The key is where the browser process runs: installing a font on your laptop does not install it inside a Docker container or a separate CI runner.
1. Find the environment that launches Chromium
Before changing packages, establish where Playwright starts the browser. The right place for the font installation depends on that answer.
| Setup | Where to install the font | What to update |
|---|---|---|
| Playwright on Ubuntu directly | The Ubuntu machine or VM running the browser | Install the package, then launch a fresh browser process |
| Playwright in Docker | The image or container running the browser | Update the image and rebuild it |
| Playwright on CI | The runner environment that launches Chromium | Update the runner image or install the package in the job before capture |
| Remote browser | The remote host or browser image | Update the environment that actually renders the page |
Playwright’s official Docker guidance covers browser system dependencies, custom images, and remote browser execution. If a remote browser performs the capture, a font installed only on the client will not affect the remote rendering.
2. Install Devanagari fonts on Ubuntu
On Ubuntu 22.04 Jammy, install the Devanagari font package with apt:
sudo apt-get update
sudo apt-get install -y fonts-deva
This package listing is specific to Jammy. Before copying the command into another release’s build, check that release’s package index and choose a package that supplies Devanagari glyphs. Ubuntu’s font inventory also lists Lohit Hindi and other Devanagari font packages; the correct package name depends on the Ubuntu release and repositories available to the environment.
For a Docker image
Add the package installation to the image used for screenshot capture. For a Jammy-based image:
FROM mcr.microsoft.com/playwright:v1.52.0-noble
USER root
RUN apt-get update \
&& apt-get install -y --no-install-recommends fonts-deva \
&& rm -rf /var/lib/apt/lists/*
The example shows the package installation pattern; select an image tag based on the Ubuntu release and Playwright version used by your project. The tag above is Noble, so check that release’s package index before relying on Jammy’s package details. If you specifically use Jammy, select the matching Playwright image variant where available. Rebuild the image after changing its package list and run captures in the rebuilt image.
Playwright’s Docker documentation recommends pinning the image version so its Playwright version matches the version in the project. Its Jammy Dockerfile installs browser dependencies with playwright-core install-deps before installing browser binaries. System font packages belong in the browser image configuration too.
For a CI job
If the runner is disposable, install the package during the job or build and use a custom runner image. The installation must happen before the job launches the browser:
sudo apt-get update
sudo apt-get install -y fonts-deva
npx playwright test
Use the package appropriate to the runner’s Ubuntu release, and make sure the job has permission to install system packages. If the runner uses a container, put the installation in that container’s image or setup instead of changing the outer host.
3. Capture a page with Hindi text
Use a page or fixture containing the actual Hindi strings your application needs to render. This minimal Playwright script opens a local page, waits for the document fonts, and saves a screenshot:
import { chromium } from 'playwright';
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage({ viewport: { width: 1200, height: 800 } });
await page.setContent(`
<!doctype html>
<html lang="hi">
<meta charset="utf-8">
<style>
body { font-family: sans-serif; font-size: 32px; }
</style>
<p>नमस्ते दुनिया — हिंदी पाठ की जाँच</p>
</html>
`);
await page.evaluate(() => document.fonts.ready);
await page.screenshot({ path: 'hindi.png' });
await browser.close();
Save this as an ES module file such as capture.mjs in a project with Playwright installed, then run node capture.mjs in the same environment that has the font package. This is a diagnostic example, not a claim that a particular screenshot was executed during research. Compare the output with your application screenshot and check whether the browser can access the intended font in that runtime.
4. Troubleshoot the remaining rendering problems
| Symptom | Likely cause | What to do |
|---|---|---|
| Hindi renders on the host but not in Docker | The font exists on the host, not in the container | Install a Devanagari font in the browser image, rebuild it, and capture inside the rebuilt container |
| Hindi renders locally but not in CI | The runner image differs from the local machine | Install the font on the runner or use a custom runner image with the font included |
| Some glyphs appear as boxes or fallback symbols | The available fonts may not cover the needed Devanagari glyphs, or the intended font may not be accessible | Verify the package’s script coverage for the target Ubuntu release and inspect the output using representative application text |
The package command cannot find fonts-deva |
The package name or repository availability differs on that Ubuntu release | Check the release-specific Ubuntu package index and select its Devanagari font package |
| Playwright cannot find its browser after an image update | The image and project may use mismatched Playwright versions | Pin a compatible image version and keep it aligned with the project dependency, following the official Docker guidance |
| A rebuild makes no visible difference | The capture may still be using an old image, a different runner, or a remote browser | Confirm which environment launches Chromium and ensure that exact environment was rebuilt or updated |
| Text remains incorrect after the font is installed | Font availability may not be the only issue | Check font loading and browser rendering in the same runtime with the actual page and strings; the available sources do not establish one universal follow-up cause |
5. Keep the screenshot runtime reliable
- Make fonts part of the image: a rebuilt image makes the font dependency reproducible across containers and CI jobs.
- Pin compatible versions: keep the Playwright Docker image aligned with the project’s Playwright version to avoid browser executable lookup problems.
- Validate after image changes: capture representative Hindi content after updating the image, runner, or browser version.
- Check the actual capture path: local, containerized, CI, and remote browser execution can each have different installed fonts.
Installing a system font adds an image dependency and may require rebuilding or updating the runner. The cited sources provide no benchmark for the effect of this package on capture time or image size, so measure those in your own build if they matter to your deployment.
Or skip the browser setup
ScreenshotNeo is a website screenshot API: one GET request returns an image or PDF, so you do not need to install or manage Playwright browsers for that capture. See the ScreenshotNeo API documentation.
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 are accepted like a visitor; 60+ known consent platforms, newsletter popups, and chat widgets are removed before the shot. Each step can be turned off.
- Bot checks and CAPTCHAs, blank pages, failed loads, timeouts, and cache hits are not billed; response headers identify the page verdict and billing status.
- An MCP server gives AI agents tools for screenshots, page information, and PDF capture.
- The Free plan includes 1,000 screenshots a month with no card. Paid plans start at $5 for 3,000 screenshots.
Sign up free for 1,000 screenshots a month with no card.
FAQ
Does Hindi text require a special Playwright option?
The cited guidance points to system font availability in the Linux browser runtime. Start by installing a font with Devanagari coverage where Chromium runs.
Will installing a font on my computer fix screenshots made in CI?
Only if the CI browser runs in that same environment. A separate runner or container needs the font installed in its own runtime.
Is fonts-deva the right package for every Ubuntu version?
The cited package listing is for Ubuntu 22.04 Jammy. Check the package index for your target release before using that package name elsewhere.
Do I need to reinstall Playwright after adding the font?
The font change belongs in the environment that runs the browser. Rebuild or update that environment, then capture again; keep the browser image and project Playwright versions aligned.


