Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If Puppeteer-generated PDFs use different fonts or line widths on a developer machine, in CI, or in a container, first check that each runtime can access the intended font files and that the page has finished loading them. Then compare the browser and operating-system versions, print CSS, and PDF options. page.pdf() uses print media by default and waits for fonts by default, but neither behavior installs missing fonts or guarantees identical rendering across operating systems.

Why the same Puppeteer page can produce different PDF fonts

A page may still display readable text when its requested font is unavailable: the browser can substitute a fallback. Because fonts have different glyph shapes and metrics, a fallback can change character widths, line breaks, pagination, and overall layout. Even when the intended font is present, differences in browser versions, operating systems, font coverage, CSS, or loading state can affect output.

Puppeteer’s PDF guide and API reference document the defaults for PDF generation, while its troubleshooting guide shows that container setups may need additional fonts and system packages. Those defaults help narrow a diagnosis; they do not promise pixel-identical output across different environments.

Check the font family, style, and print CSS first

Inspect the rendered page under the same media mode used for the PDF. page.pdf() generates with print CSS media by default, so a rule in @media print may select a different family, weight, size, or style from the one visible on screen. See Puppeteer’s PDF generation guide.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Identify the exact family, weight, and style expected by the document, including whether the CSS names match the supplied font face.
  2. Inspect computed styles with print media active and review relevant @media print rules for overrides.
  3. Check whether the requested family and style exist in the runtime or are being supplied as web fonts.
  4. If you specifically intend to create a screen-styled PDF, use page.emulateMediaType('screen') before calling page.pdf(). Do not use this as a general fix for missing fonts.

A print-versus-screen mismatch is a CSS-mode issue; a fallback caused by an unavailable font file is a font-access issue. Distinguishing them prevents changing browser flags when the actual problem is a stylesheet or missing asset.

Verify web fonts have loaded before PDF creation

Puppeteer’s Page.pdf() waits for fonts by default. The PDF options reference describes waitForFonts as true by default and says it waits for document.fonts.ready. If the page is backgrounded, the reference notes that bringing it to the foreground may be necessary. See the PDF options reference and Page.pdf() API.

For diagnosis, inspect the font loading status and the faces the document knows about. Also check the browser’s network activity for failed font requests. Waiting for the document’s font set to settle does not make a failed request succeed, and it cannot provide a font that is neither installed nor served.

const status = await page.evaluate(() => document.fonts.status);
console.log('document.fonts.status:', status);

const faces = await page.evaluate(() =>
  Array.from(document.fonts, face => ({
    family: face.family,
    style: face.style,
    weight: face.weight,
    status: face.status
  }))
);
console.table(faces);

await page.pdf({ path: 'output.pdf' });

When troubleshooting, remove any waitForFonts: false override and test again. If an application deliberately turns waiting off, confirm that the font requests and face statuses are ready before producing the PDF.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make the intended fonts available in every runtime

Browsers do not automatically contain every proprietary or application-specific font. Install the fonts the document needs in each host or container, or deliver them from the application as web fonts and verify the running browser can load them. A font installed on a developer’s laptop is not automatically present in a CI image.

Puppeteer’s troubleshooting guide includes Linux dependency guidance and Docker examples that install extra font families for broader script coverage, including Chinese, Japanese, Arabic, Hebrew, and Thai. Its examples also include libfontconfig1. The package set depends on the Linux distribution; check the current system requirements rather than copying a package list intended for another image.

Font coverage matters as much as font presence. A family may render Latin text but lack glyphs for other scripts or characters, leading to mixed fonts within a single document. Verify coverage for the actual content, and ensure every deployment image receives the same required font files and relevant browser libraries.

Compare environments with controlled inputs

When the font differs only in one environment, record and compare the inputs that can change rendering. Puppeteer’s system-requirements page lists supported platforms, including Windows x64, macOS x64 and arm64, and Linux distributions and architectures; consult it for the applicable platform-specific package requirements. A supported platform does not imply identical font rendering across platforms.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
What to compare What to record or verify
Font source System-installed font files versus application-served web fonts; confirm the expected family, style, and weight are accessible.
Runtime Puppeteer and Chrome or Chrome for Testing versions, operating-system distribution, and architecture.
CSS mode Print media, the default for page.pdf(), versus screen media if explicitly selected.
Load state Whether custom font requests succeeded and font loading completed before PDF generation.
Glyph coverage Whether the available font files include the scripts and characters used in the document.
PDF options Any explicit settings that affect output, including a changed waitForFonts value.

Render the same HTML and assets in each environment, record the inputs above, and change one variable at a time. This is a diagnostic method, not a guarantee that separate operating systems will produce identical PDFs.

Runnable Puppeteer example with font checks

The following Node.js example navigates to a page, reports font loading information, and creates a PDF using the documented font-wait default explicitly. Replace the URL with the page you need to render.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();
    await page.goto('https://example.com', { waitUntil: 'networkidle0' });

    const fontInfo = await page.evaluate(() => ({
      status: document.fonts.status,
      faces: Array.from(document.fonts, face => ({
        family: face.family,
        style: face.style,
        weight: face.weight,
        status: face.status
      }))
    }));
    console.log(JSON.stringify(fontInfo, null, 2));

    await page.pdf({
      path: 'output.pdf',
      printBackground: true,
      waitForFonts: true
    });
  } finally {
    await browser.close();
  }
})().catch(error => {
  console.error(error);
  process.exitCode = 1;
});

networkidle0 is used here as a navigation condition, not as proof that a particular font face is correct or available. For diagnosis, inspect the font information and failed requests as well as the PDF. If a font is missing from the runtime or a web-font request fails, fix that underlying condition rather than relying on the wait option.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Use rendering flags only after matching the inputs

A Puppeteer issue reports PDF font-width differences between desktop Chrome printing and Puppeteer in particular environments, with variation by font and environment. It is evidence that such discrepancies have been reported, not that a single flag or universal remedy resolves them. The issue discussion includes a suggestion to try a Chromium font-rendering flag, but it is not official support guidance or a demonstrated general fix. See the reported Puppeteer issue.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
The SQL Programming Language: .
  • Used Book in Good Condition

First align the fonts, CSS mode, font-loading state, Puppeteer and browser versions, and host image. If you test a flag, validate it in each target environment against the actual document; do not treat an issue comment as a compatibility guarantee.

Troubleshoot common symptoms

  • Text looks right in the browser but wrong in the PDF: inspect print-specific font rules and compare computed styles under print media. The PDF path uses print media by default.
  • Only CI or the container uses a different face: check installed fonts and font libraries in that exact runtime. Add the required font files to the deployment image or serve them from the application.
  • Some characters use a different-looking face: verify glyph coverage for those scripts and characters; add suitable font files if the selected family does not cover them.
  • A web font works intermittently or falls back: inspect font request failures and face statuses before PDF generation. Keep the default font wait enabled while diagnosing.
  • The page is backgrounded and fonts are not ready: follow the PDF options guidance and bring the page to the foreground when needed.
  • Changing a Chromium flag has no consistent effect: restore a controlled baseline and compare font inventory, browser/runtime, CSS, and loading state before further flag experiments.
  • One environment paginates differently despite matching CSS: compare exact font files and runtime versions, then reproduce with identical HTML and assets while changing one input at a time. Different operating systems are not promised to render identically.

Or skip the browser setup

For a screenshot rather than a Puppeteer-generated PDF, ScreenshotNeo provides a website screenshot API and MCP server. Its one-call API can return PNG, JPEG, WebP, or PDF output. This does not configure fonts in your own Puppeteer runtime, but it can avoid maintaining browser setup for a capture workflow.

For example, a cURL request that saves a WebP capture is:

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 documentation for API options and setup. Cookie banners are accepted like a visitor and more than 60 known consent platforms, newsletter popups, and chat widgets are removed before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify the page verdict and billing status in headers. An MCP server offers take_screenshot, get_page_info, and capture_pdf for AI agents. The free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Sign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month with no card.

Frequently Asked Questions

Does waitForFonts: true install a missing font?

No. It waits for the document’s font-loading state; the font still needs to be installed in the runtime or successfully served by the page.

Does matching Puppeteer versions guarantee identical PDF fonts on different operating systems?

No. Font availability and platform differences can still affect output; the documentation does not promise pixel-identical PDFs across operating systems.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.