Struggling with missing emojis in wkhtmltopdf PDFs? Learn why they don’t render by default and discover simple fixes using emoji fonts or Twemoji SVG/PNG.

How to display emojis in WKHTMLTOPDF

Emojis have become an integral part of modern digital communication. From adding personality to messages to improving the readability of user interfaces, their use goes far beyond casual texting. Developers often face the challenge of ensuring that emojis are displayed correctly in different contexts, including the generation of PDF documents.  One of the most popular tools for converting HTML into PDFs is wkhtmltopdf, but by default, it does not always handle emojis as expected. Missing characters, blank spaces, or placeholder symbols (�) often appear instead of the intended icons.

In this article, I'm going to explain to show you a workaround to properly configure wkhtmltopdf to render emojis seamlessly in your PDFs.

Why emojis don't appear in PDFs generated by wkhtmltopdf

The issue with wkhtmltopdf is that its outdated Qt/WebKit rendering engine does not support modern color-font technologies such as SBIX, CBDT/CBLC, COLR/CPAL v0/v1, or SVGinOT. As a result, newer emojis (e.g., 😀 😁) will not display correctly by default.

In addition, other factors can also prevent emojis from appearing, such as:

  • Not implementing a global emoji font in the document.
  • HTML not set to UTF-8 (missing <meta charset="utf-8"> or wrong --encoding) or stripping Unicode variation selectors (FE0F/FE0E) or ZWJ sequences can break certain emojis or combinations.

There are two options that you can implement to make them show up reliably:

1. Implementing an emoji font

One of the most reliable ways to make emojis appear correctly in wkhtmltopdf is by explicitly embedding an emoji-capable font in your HTML. Since wkhtmltopdf relies on the fonts available in the system or those you provide, adding a font such as Noto Emoji ensures that each emoji character has a valid glyph to render. Noto Emoji is an open source font that has you covered for all your emoji needs, including support for the latest Unicode emoji specification. It has multiple weights and features thousands of emojis.

To do this, you can download the font (for example, NotoEmoji-Regular.ttf) and load it with @font-face in your CSS. Then, apply this font to the specific elements that include emojis by setting a custom class, like .emoji { font-family: 'NotoEmoji', sans-serif; }. When running wkhtmltopdf, remember to enable local file access so the converter can load your font files. This approach produces consistent results across platforms, though the emojis will appear in monochrome since wkhtmltopdf does not support modern color-font formats.

The following HTML can be rendered in wkhtmltopdf and should render a PDF with emojis (without color layers) as it uses the Google Fonts CDN:

<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Dynamic Success Page</title>
    
        <!-- 1. Include Noto Emoji Font -->
        <link rel="preconnect" href="https://fonts.googleapis.com">
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link href="https://fonts.googleapis.com/css2?family=Noto+Emoji:[email protected]&display=swap" rel="stylesheet">
        <style>
            /** 2. Specify items with the .emoji class implement the Noto Emoji font family **/
            .emoji {
                font-family: "Noto Emoji", sans-serif;
                font-optical-sizing: auto;
                font-style: normal;
            }
        </style>
    </head>
    <body>
        <h1>
            This is a PDF with emojis 🎉 and special characters © ® ™
        </h1>
        <p class="emoji">
            The experience of using emojis in web pages is great! 🧑‍💻⚙️✈️☕
        </p>
    </body>
</html>

2. Replacing Emojis with an Image Library

Now the first options works pretty well to display emojis in black layers, but colors are not functional. If you need full-color emojis in your PDFs, a practical alternative is to replace emoji characters with images from a library such as Twemoji. This method bypasses the font limitations of wkhtmltopdf by converting each emoji into a small PNG or SVG image before the PDF is generated. You can achieve this either with JavaScript using the official Twemoji parser to scan your HTML and swap emojis with <img> tags—or through server-side preprocessing that replaces emoji codepoints with image references.

While this approach requires shipping image assets and slightly increases the document size, it guarantees colorful, consistent emoji rendering regardless of the platform. By using SVGs or properly scaled PNGs, you can also control the size and alignment of each emoji, ensuring they integrate smoothly with surrounding text:

<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Dynamic Success Page</title>
        <style>
            img.emoji {
                height: 2em !important;
                width: 2em !important;
                vertical-align: -0.25em;
                margin: 0 0.1em;
            }
        </style>
    </head>
    <body>
    <h1>Color emojis can be used with inline images</h1>
    <p id="line">
        Rene emojis 😀 and mixed text 😍 👍 🧑‍💻 ✈️ ☕  🤚🖐️✋🖖🫱🫲🫳🫴👌🤌🤏✌️🤞🫰🤟🤘🤙👈👉👆🖕👇☝️🫵👍👎✊👊🤛🤜👏🙌🫶👐🤲🤝🙏✍️💅🤳💪🦾🦿🦵🦶👂🦻👃🧠🫀🫁🦷🦴👀👁️👅👄🫦👶🧒👦👧🧑👱👨🧔🧔‍♂️🧔‍♀️👨‍🦰👨‍🦱👨‍🦳👨‍🦲👩👩‍🦰🧑‍🦰👩‍🦱🧑‍🦱👩‍🦳🧑‍🦳👩‍🦲🧑‍🦲👱‍♀️👱‍♂️🧓👴👵🙍🙍‍♂️🙍‍♀️🙎🙎‍♂️🙎‍♀️🙅🙅‍♂️🙅‍♀️🙆🙆‍♂️🙆‍♀️💁💁‍♂️💁‍♀️🙋🙋‍♂️🙋‍♀️🧏🧏‍♂️🧏‍♀️🙇🙇‍♂️🙇‍♀️🤦🤦‍♂️🤦‍♀️🤷🤷‍♂️🤷‍♀️🫅🤴👸👳👳‍♂️👳‍♀️👲🧕🤵👰🤰🤱👩‍🍼💃🕺🛀🛌🧑‍🤝‍🧑👭👫👬💏👩‍❤️‍💋‍👨👨‍❤️‍💋‍👨👩‍❤️‍💋‍👩💑👩‍❤️‍👨👨‍❤️‍👨👩‍❤️‍👩💌💘💝💖💗💓💞💕💟❣️💔❤️‍🔥❤️‍🩹❤️🧡💛💚🤎🖤🤍
    </p>
    <!-- Twemoji will replace the characters with <img> tags -->
    <script src="https://twemoji.maxcdn.com/v/latest/twemoji.min.js" crossorigin="anonymous"></script>
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            twemoji.parse(document.getElementById('line'), {
                folder: '72x72', ext: '.png', className: 'emoji'
            });
        });
    </script>
    </body>
</html>

Don't forget that the methods here mentioned load a remote resource (and plenty of them in the images approach), so be sure to adapt that to your environment to prevent files from being loaded from the CDN of the library. There are important things to consider in this approach and which can help you to optimize the generation time of the PDF:

  • Self-host all assets and host only the emojis that you know are allowed in your application to reduce the number of possible assets.
  • Subset what you ship, don’t copy the entire Twemoji repo or a full Unicode font if you only use a handful of emojis.
  • Inline when it helps. For a tiny, fixed emoji set (e.g., 5–10 icons), inline as data URIs in CSS/HTML to cut file I/O. (Trade-off: bigger HTML, but zero extra reads.)

Happy coding ❤️!


Senior Software Engineer at Software Medico. Interested in programming since he was 14 years old, Carlos is a self-taught programmer and founder and author of most of the articles at Our Code World.

Sponsors