If the Indian rupee sign (₹) appears as a box in a Puppeteer screenshot, Chrome did not have a usable glyph for that character at capture time. Check that the text is U+20B9, verify which font the element actually uses, and make sure that font has loaded or is installed in the browser’s runtime. A CSS font-family name alone does not guarantee that the corresponding font file contains the glyph.
1. Confirm the character is the rupee sign
The Indian rupee sign is ₹, Unicode U+20B9. First check the actual page data, not just how the character looks in an editor. A similar-looking character, a replacement character, or damaged text will not be fixed by installing a font.
As an Amazon Associate I earn from qualifying purchases.
const text = '₹';
console.log([...text].map(char =>
`U+${char.codePointAt(0).toString(16).toUpperCase()}`
));
The expected output is U+20B9. You can also temporarily render a test string such as ₹ 123.45 in the same page and browser process used for the screenshot.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →2. Check the element’s font and fallback stack
Inspect the affected element in Chrome DevTools or evaluate its computed style from Puppeteer. The computed font-family shows the requested stack, but it does not prove that the selected font file contains U+20B9. If the first family lacks a character, browsers can try subsequent families in the stack. Noto’s font guidance describes this fallback behavior.
#1 Best Overall
const result = await page.$eval('#price', element => ({
text: element.textContent,
fontFamily: getComputedStyle(element).fontFamily
}));
console.log(result);
Use a stack that names the intended web or system font first and a tested fallback after it. Confirm that the actual font file selected in the capture environment supports U+20B9. Do not assume that a font’s name or broad script label guarantees coverage of every currency symbol. The Noto Sans Devanagari specimen documents script coverage, but is not a per-file verification of this particular glyph.
3. Wait for the web font before taking the screenshot
If the page fetches fonts over the network, a screenshot can happen before the intended font is ready. Puppeteer’s screenshot guide documents Page.screenshot() and shows navigation with a wait condition; it does not state that a screenshot call automatically waits for fonts. Wait for navigation and the page’s relevant content, then wait for the document’s font set before capture.
await page.goto('https://example.com', { waitUntil: 'networkidle0' });
await page.waitForSelector('#price');
await page.evaluate(async () => {
await document.fonts.ready;
});
await page.screenshot({ path: 'page.png' });
Replace the URL and selector with those for your page. document.fonts.ready resolves when fonts used by the document have completed loading or failed; it cannot make a missing or unsupported glyph appear. Check the browser’s network panel or font-loading errors as well as the screenshot. For Puppeteer’s documented screenshot API and navigation example, see Puppeteer Screenshots.
Rank #2
4. Check the browser’s operating system and container
A font installed on your workstation may not be installed in the Linux container or CI image that launches Chrome. Test U+20B9 in the browser process that creates the screenshot, not only in a host-machine font viewer. Compare the runtime image, installed font files, font configuration, and access to remote font URLs between a working local run and a failing CI run.
Puppeteer’s troubleshooting guide lists libfontconfig1 among common Chrome Linux dependencies and documents font packages for some distributions. This is evidence that runtime setup matters, not a universal package recipe for rupee support: package names and required font files vary by distribution and image.
Install the selected font files and required font configuration into the image that runs Chrome. Refresh the font cache or restart applications when the operating system’s font setup requires it; Noto’s guide notes that some applications recognize new fonts after cache updates while others need a restart. For a reliable check, start a fresh browser process after changing fonts and render the U+20B9 test string again.
5. Make Puppeteer runs reproducible
Record the browser version, operating system or base image, font files, and whether fonts are fetched remotely. These details help distinguish a CSS or network timing problem from a runtime-font difference when screenshots change in CI.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problems- The
puppeteerpackage downloads a compatible Chrome for Testing browser as part of its installation. puppeteer-coredoes not download Chrome; you manage and provide the browser yourself.
Those browser-management differences are described in the Puppeteer installation guide. If you use puppeteer-core, include the externally managed browser version in your run records.
6. Choose the repair that matches the failure
| What you find | Likely repair | Verify |
|---|---|---|
| The page has the wrong character or malformed text | Correct the source data or encoding so it contains U+20B9. | Inspect the code point in the page data and render a test string. |
| The intended web font is late, missing, or lacks U+20B9 | Fix the font request or CSS stack; provide a fallback with the glyph. | Confirm the font request succeeds, check actual glyph coverage, and wait for font readiness before capture. |
| The browser runtime lacks the font that works locally | Install and configure an appropriate font in the browser’s OS/container image. | Test in a fresh browser process inside that same image. |
| The issue occurs only in CI | Compare browser version, base image, font inventory and configuration, and network access to remote fonts. | Reproduce the capture using the same runtime and inputs as CI. |
These causes can overlap. For example, a page can depend on a remote font and also have no suitable system fallback when that request fails.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Common troubleshooting errors
The CSS names a font, but the rupee sign is still a box
A family name in a CSS stack does not establish that the font file is installed, loaded, or contains U+20B9. Check the selected font and verify the exact glyph; add a fallback that you have tested in the capture runtime.
Waiting for page load did not fix it
Navigation readiness and font readiness are different checks. Wait for the content you need and for document.fonts.ready, then inspect whether the font request failed or the chosen file lacks the character.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
It works on a laptop but fails in a container
The environments may have different font files or configurations. Install the necessary font in the image that actually launches Chrome, refresh or restart as appropriate, and test there rather than relying on the host’s fonts.
Installing one generic Linux font package changed nothing
There is no universal package fix established for every Linux distribution and image. Check the specific font file and U+20B9 coverage, plus the runtime’s font configuration, instead of assuming a package with a broad script name contains the needed symbol.
Or skip the browser setup
If you need a screenshot without managing a local browser and font environment, ScreenshotNeo is a website screenshot API and MCP server. A single GET request can return a PNG, JPEG, WebP, or PDF. The API accepts the parameter names used by other screenshot APIs, which can make switching easier. This example captures the same test page; confirm the page’s own font setup if the rupee glyph is missing from the page itself.
curl -G "https://api.screenshotneo.com/v1/shot"
-d access_key=YOUR_API_KEY
--data-urlencode url=https://example.com
-o shot.webp
See the ScreenshotNeo API documentation for request options. Before capture, it accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots a month without a card; paid plans start at $5 for 3,000 screenshots.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Sign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month with no card.
Frequently Asked Questions
Does Puppeteer’s screenshot method wait for fonts automatically?
The Puppeteer screenshot documentation does not promise automatic font readiness. Wait for the relevant page content and, when needed, await `document.fonts.ready` before calling `page.screenshot()`.
Does Puppeteer wait for fonts when generating a PDF?
Puppeteer’s PDF guide, labeled version 25.12.0, says `Page.pdf()` waits for fonts by default. That documented behavior is specific to PDF generation and should not be assumed for screenshots.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Free tools Windows power users keep installed
One-click scans. No signup required.

