Free tools Windows power users keep installed
One-click scans. No signup required.
If emojis appear as empty squares in an HTML-generated PDF, the renderer usually cannot find a font with a usable glyph for the character or sequence. Make the needed font available to the PDF process, check fallback fonts and print-specific CSS, then test the exact emoji through the production rendering path. If that sequence still is not supported, use an image or clear text alternative.
Why emojis become empty boxes in PDFs
An empty square, often called a tofu glyph, generally means the selected font and available fallback fonts do not contain a usable glyph. In Chromium’s Blink text stack, the browser tries CSS fonts and then system fonts for missing glyphs; if fallback cannot fill the gap, it displays the primary font’s .notdef glyph. Chromium’s font documentation describes this behavior.
As an Amazon Associate I earn from qualifying purchases.
A font name in your CSS is not enough by itself: the matching font must be installed or otherwise available to the process that creates the PDF, and the renderer must be able to use it for fallback. A desktop browser and a server-side worker may have different fonts, operating systems, and font configuration.
Diagnose the PDF rendering environment
- Identify the renderer and runtime. Record the engine and version, operating system, and whether PDF generation runs in a container, remote worker, or local process.
- Make a minimal reproduction. Put the exact failing emoji in a small HTML file and generate a PDF with the same code path and runtime as the affected document. Preserve variation selectors, skin-tone modifiers, flags, keycaps, and zero-width-joiner (ZWJ) characters; visually similar sequences can require different font support.
- Check fonts where PDF generation runs. For WeasyPrint, use
fc-listto list discoverable fonts andfc-matchto see which font Fontconfig matches. Run these in the same container or worker as PDF generation, not only on your workstation. See the WeasyPrint 70.0 API reference. - Inspect the PDF-specific styles. Compare the font declarations in normal CSS and
@media print. Puppeteer’sPage.pdf()uses print media by default, so a font stack that works on screen may not be the one used in the PDF. Puppeteer documents the PDF method. - Read renderer warnings and verify the output. WeasyPrint documents a warning and .notdef output when neither the selected font nor fallback supports a character. Check the generated PDF in the viewers your users rely on; font embedding does not guarantee that every viewer presents every emoji sequence identically.
Fixes by renderer
Chromium and Puppeteer
Install or provide a font with the required coverage in the browser process environment, then confirm that Chromium can discover it and use it as fallback. Review both the CSS font stack and any print overrides. Test the generated PDF rather than relying on the browser’s screen rendering.
#1 Best Overall
- Used Book in Good Condition
If the intended PDF should use screen styles rather than print styles, Puppeteer documents selecting screen media before creating the PDF:
await page.emulateMediaType('screen');
await page.pdf({ path: 'output.pdf' });
Use this only when screen media is actually the desired layout; it changes the styles used for PDF output, not the underlying emoji font coverage.
Rank #2
- Used Book in Good Condition
WeasyPrint
WeasyPrint uses fonts Pango can find, with Fontconfig involved in font discovery. Install the needed font in the PDF runtime and check the match with fc-list and fc-match. WeasyPrint 70.0 says fonts are embedded and subset by default to glyphs used in the PDF. Its documentation also notes that Fontconfig defaults may provide colored emoji variants, while configuration can interfere with CSS font rules. If no available font or fallback supports a character, WeasyPrint renders .notdef and logs a warning. Consult the WeasyPrint 70.0 API reference for the runtime and font details.
Recommended Free Tools
wkhtmltopdf
An individual issue report opened April 27, 2016 describes an empty square instead of ☕️ in a generated PDF; it is a symptom report, not a confirmed universal diagnosis or fix. The wkhtmltopdf repository was archived on January 2, 2023. Treat that issue as historical context, and take the renderer’s archived status into account when choosing a new PDF pipeline. View the reported issue and the archived repository.
Rank #3
Test emoji sequences, not just individual characters
Emoji that look like one symbol may be encoded as multiple characters. Flags, keycaps, skin-tone variants, and ZWJ combinations can fail even when a related standalone emoji works. Verify the exact sequence used in your content with the exact renderer, installed fonts, and deployed runtime. Font support in one browser or operating system does not establish support in another. See Unicode Technical Standard #51 for emoji sequence concepts.
When font changes are not enough
If the required sequence still renders as tofu after confirming font discovery, fallback, and print styles, do not silently ship the square. Use an image asset for the symbol or replace it with a clear text alternative. Choose the approach that fits the document’s accessibility and portability needs; there is no single image workflow established for every HTML-to-PDF renderer.
Rank #4
Choose a reliable PDF workflow
When comparing renderers or changing a pipeline, check the exact emoji set (including ZWJ and modifier sequences), production font discovery, print-media behavior, font embedding and subsetting, and the renderer’s maintenance status. Test the deployed versions and runtime rather than assuming a font or configuration will behave identically across engines. The cited documentation describes individual engines; it does not establish a cross-engine benchmark.
Or skip the browser setup
If you need a screenshot rather than a PDF, ScreenshotNeo is a website screenshot API and MCP server. A GET request returns an image or PDF; its cleanup steps accept cookie banners and remove known consent banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. AI agents can use its MCP tools to take screenshots, get page information, and capture PDFs. It includes 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000.
For a one-call screenshot, create an API key and run:
Best Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for parameters and output options. Sign up for 1,000 free screenshots a month, with no card required.
Frequently Asked Questions
Why does the same emoji work in a browser but not in its PDF?
PDF generation may use a different runtime font set or print-specific CSS. Check the fonts and media styles used by the PDF process.
Will embedding fonts guarantee emoji display in every PDF viewer?
No. Embedding and subsetting help portability, but they do not guarantee identical display of every emoji sequence in every viewer.
What if only a combined emoji, such as a flag or family, fails?
Test the exact sequence. Combined emoji can require sequence support beyond coverage for individual characters.
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.




