October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
emoji

How to Fix Gray Emojis in Headless Chrome PDF Output

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

Gray emojis in a Puppeteer PDF usually point to how Chrome prints the page or to the emoji font available in the runtime—not to a single universal bug. First preserve print colors or render with screen media; if emojis are still monochrome, make the font fallback deterministic or replace those glyphs with SVG/PNG assets. Test the resulting PDF in the same Chrome build and environment used in production.

Why emojis turn gray in a headless Chrome PDF

Puppeteer’s page.pdf() uses the print CSS media type by default. Chrome may also modify colors for printing. Those behaviors can make a page’s PDF appearance differ from its on-screen rendering, including the appearance of emoji. Puppeteer documents both the print-media default and the -webkit-print-color-adjust control for preserving exact colors: Puppeteer PDF options.

Emoji rendering also depends on the fonts installed in the operating system and Chrome’s fallback choices. Noto Color Emoji uses the CBDT/CBLC color-font format; support and font fallback vary by platform, and Linux may need fontconfig adjustments. See the Noto Emoji project. A font that looks colorful in desktop Chrome is not proof that the same glyph will render in a PDF from a Linux container.

There is no documented universal fix or guaranteed Chrome-version matrix for gray PDF emoji. Treat media settings, font selection, and the PDF viewer as separate variables, and validate the output in the production environment.

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

Fix print color handling first

If you want to keep print media, tell Chrome to preserve exact colors. Add this rule to the page’s print stylesheet or inject it before generating the PDF:

@media print {
  *, *::before, *::after {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}

Puppeteer documents -webkit-print-color-adjust as the way to force exact colors in PDF printing. The unprefixed property is included alongside it in the rule. This controls print color adjustment; it does not install an emoji font or guarantee that every color-font glyph is embedded and displayed identically by every PDF viewer.

Choose screen or print media deliberately

Use screen media when the PDF should resemble the web page

If the PDF is meant to look like the rendered screen page, switch the emulated media type before calling page.pdf(). Wait for the page’s fonts to be ready, and enable print backgrounds so background colors and images are included:

await page.emulateMediaType('screen');
await page.evaluate(() => document.fonts.ready);
await page.pdf({ path: 'output.pdf', printBackground: true });

page.pdf() otherwise generates using print media. Switching to screen media changes which media-specific CSS applies, so check page layout, pagination, and backgrounds as well as emoji color. Use print media instead when print styles are an intentional part of the document design.

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

Minimal complete Puppeteer capture

This example starts with a URL, waits for network activity to settle, selects screen media, injects exact-color print styling, waits for fonts, and writes a PDF. It assumes Puppeteer is installed and that url is set to the page you intend to capture.

const puppeteer = require('puppeteer');

async function savePdf(url) {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();
    await page.goto(url, { waitUntil: 'networkidle0' });
    await page.emulateMediaType('screen');
    await page.addStyleTag({
      content: `
        @media print {
          *, *::before, *::after {
            -webkit-print-color-adjust: exact;
            print-color-adjust: exact;
          }
        }
      `,
    });
    await page.evaluate(() => document.fonts.ready);
    await page.pdf({ path: 'emoji.pdf', printBackground: true });
  } finally {
    await browser.close();
  }
}

savePdf('https://example.com').catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

Replace the example URL with your target. The font wait is useful when web fonts load asynchronously, but it does not guarantee that the intended emoji font exists or that Chrome selected it.

Make emoji font selection predictable

When the media and color adjustments do not solve the problem, inspect the fonts available to the exact Chrome process that creates the PDF. On Linux, review fontconfig configuration and verify which font Chrome actually uses for the affected glyphs. Noto’s project notes that Linux may require fontconfig changes, and its build tooling produces CBDT and COLRv1 variants, making color-font format another compatibility variable: Noto Emoji and Noto Emoji build resources.

  1. Identify the runtime. Record the operating system, container image, and Chrome/Chromium build used for PDF generation. Reproduce the issue there rather than relying on a developer’s desktop browser.
  2. Check installed fonts and fallback. Confirm that the intended emoji font is installed and that the runtime’s fontconfig rules make it available to Chrome.
  3. Declare a controlled font path. Bundle or install a tested color emoji font and use an explicit @font-face rule or a deliberate fallback list. Ensure the font file is served or readable by the page.
  4. Wait before capture. Await document.fonts.ready after navigation and any style changes that introduce fonts.
  5. Render and inspect a test sheet. Include the exact emoji and sequences your application uses, then inspect the generated PDF in the target viewer.

Avoid assuming that explicitly naming a font always improves output. Noto issue #350 records spacing problems when “Noto Color Emoji” is selected explicitly and reports different behavior from fallback configuration: Noto Emoji issue #350. Test the actual CSS and fontconfig combination rather than copying a family name without verification.

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

Use SVG or PNG for fixed emoji when reliability matters most

If a document uses a known, fixed set of emoji and color-font rendering remains unstable, replace those characters with inline SVG or PNG assets before capture. This makes the output depend on image rendering rather than whether a color emoji font is installed, selected, and supported through PDF generation. Use assets from an approved emoji library, and check that the asset license and visual style fit your project.

Approach Color fidelity and portability Dependencies and trade-offs
Print color adjustment Addresses Chrome’s print color modification; does not guarantee identical output in every PDF viewer. Still relies on the runtime’s font availability and fallback.
Screen media Can make PDF styling follow screen CSS rather than print CSS. Can alter layout and pagination; emoji still depend on fonts and viewer behavior.
Controlled color font Can stabilize glyph selection when the chosen format works in the target environment. Requires font installation, correct fallback, and validation across target operating systems. Font-format support differs.
SVG or PNG assets Removes the emoji font fallback dependency for the replaced glyphs. Requires managing assets, licensing, visual consistency, and sequence coverage; images can increase PDF size.

When choosing, test color fidelity in the target PDF viewer, portability across Linux containers and desktop systems, ZWJ and skin-tone sequences, file size, and asset licensing. SVG/PNG is an engineering fallback, not a claim that all font-based emoji output is inherently unreliable.

Control readiness for command-line PDF capture

For direct Chrome headless command-line capture, Chrome documents --print-to-pdf, --timeout, and --virtual-time-budget as PDF and timing controls: Chrome Headless mode. These can help when page content or emoji assets load asynchronously, but they do not install or select an emoji font.

chrome --headless --print-to-pdf=output.pdf --timeout=5000 --virtual-time-budget=5000 https://example.com

Adjust timing to the page rather than treating a fixed delay as proof that fonts are ready. If reliable font readiness is necessary, Puppeteer gives you direct access to document.fonts.ready before page.pdf().

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.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot gray or missing emoji in the output

  • Emoji are colored on screen but gray in the PDF: page.pdf() may be applying print media and print color adjustment. Try screen media, or add the exact-color print rule.
  • Some emoji remain monochrome or appear as fallback symbols: inspect the fonts installed in the PDF runtime and the fallback actually chosen by Chrome. Confirm that the font is loaded before capture.
  • Output differs between desktop and Linux container: treat the operating system and fontconfig setup as part of the rendering pipeline. Noto documents Linux fontconfig as a possible configuration requirement.
  • Spacing changes after explicitly naming Noto Color Emoji: compare against the runtime’s fallback behavior. Explicit selection has been associated with spacing problems in Noto issue #350.
  • Emoji are absent or stale despite the right font: wait for fonts and other asynchronous page assets before capture. For CLI runs, use Chrome’s documented timing controls; for Puppeteer, wait for document.fonts.ready.
  • Only particular combined emoji fail: test the exact ZWJ, skin-tone, or other sequences used by the document. A test with a basic smiley does not establish support for every sequence.
  • Appearance varies by PDF viewer: open the same generated file in the viewer used by your users. Validate the final artifact, not just the browser page or an intermediate preview.
  • Font-based output cannot be made stable enough: substitute approved SVG or PNG assets for the fixed emoji set and check the resulting PDF for visual consistency and size.

Or skip the browser setup

If you need a website screenshot or PDF without maintaining a headless Chrome capture pipeline, ScreenshotNeo offers a one-request screenshot API and an MCP server. A GET request can return PNG, JPEG, WebP, or PDF. Its capture options include PDF paper size, margins, landscape orientation, and page ranges; the screenshot controls also include viewport and device presets, full-page capture, and waits for selectors, delays, or network idle. For a Puppeteer-specific workflow that depends on controlling a particular font and PDF rendering behavior, keep using the browser method above.

cURL example, adapted to capture a PDF of the page:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -d format=pdf -o shot.pdf

See the ScreenshotNeo API documentation for request parameters and output options. Cookie banners, newsletter popups, and chat widgets are removed before capture; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify page verdict and billing status in headers. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots.

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

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

Frequently Asked Questions

Does printBackground: true alone fix gray emoji?

No. It includes page backgrounds in the PDF; use media selection and exact-color print styling to address print color handling.

Will installing Noto Color Emoji guarantee color emoji in every PDF?

No. Font format support, fallback, operating-system configuration, and PDF viewer behavior can differ. Test the target runtime and viewer.

Do Chrome’s headless timeout flags install an emoji font?

No. They provide capture and timing controls, not font installation or selection.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

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

Read next

Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.