Why WhatsApp Emojis Print as Empty Boxes (and How to Fix It)
You export a chat, open the file, and half the hearts, thumbs and party poppers have turned into blank rectangles. Nothing is broken and nothing is missing. The emoji are still sitting in the file exactly as WhatsApp wrote them; what has failed is the chain of fonts and settings between that file and your screen or printer. Here is what is actually going on, and how to get every emoji through to a printed page or PDF intact.
An export stores emoji as text, not as pictures
A WhatsApp export arrives as a ZIP containing a plain text transcript called _chat.txt, plus the media files if you asked for them, with the text file referring to those files by name. That structure is covered in more detail in The WhatsApp Chat Export File Explained, but the important part for emoji is this: there are no emoji images anywhere in the export. A red heart in a message is stored as a Unicode character in the text file, in exactly the same way the letter "a" is.
That means the appearance of every emoji is decided at the moment something opens the file. The characters are just numbers. Whatever program reads them has to find a font that knows how to draw each one. If it cannot, you get a box. If it guesses the file's encoding wrongly, you get gibberish. If the printing path picks a different font from the one used on screen, you can get colour on the monitor and black squares on the page. Three different failures, three different fixes, and it helps enormously to know which one you are looking at.
Failure one: mojibake from the wrong encoding
If instead of boxes you are seeing strings like ð\u009f\u0098\u0080, sequences of accented Latin letters where an emoji should be, or a scattering of question marks, that is not a font problem at all. It is an encoding problem. The transcript is written in UTF-8, which can represent every Unicode character, so emoji sit happily alongside Arabic, Chinese and accented Latin text in the same file. When an editor assumes an older single byte encoding instead, it reads each byte of a multi byte emoji separately and prints nonsense. A byte order mark at the start of the file and Windows style line endings can add their own stray characters to the mess.
The fix is to reopen the file and explicitly tell the program it is UTF-8, or to use something that assumes UTF-8 by default. Browsers generally handle this correctly, which is one practical reason to read an export in a browser based viewer rather than in a text editor that has been configured for something else years ago. Mojibake is always recoverable, because the underlying bytes were never damaged.
Failure two: the empty box, which is a real glyph
The blank rectangle has a name. Every OpenType font is required to contain a glyph at index zero called .notdef, and that glyph has no Unicode code point of its own. When a rendering engine looks up a character in a font's character map and finds nothing, it falls back to glyph zero. Some environments draw the .notdef from the selected font, others substitute a system supplied fallback, which is why the box looks slightly different from one application to the next. Sometimes it is hollow, sometimes it has a cross through it, sometimes it shows tiny hexadecimal digits.
Informally this is called tofu, and it appears specifically when no font anywhere in the chain can supply a glyph for the character. It is the system admitting it does not know what the character should look like. So a box is not evidence that the emoji was lost in the export. It is evidence that the machine doing the drawing has no emoji font covering that character, or has not been told to look for one.
Browsers are helpful here, because font selection does not stop at the first available family in a CSS font stack. Selection happens one character at a time, so if the main text font has no glyph for a needed character, the browser moves on to the next font in the list for that character alone. That is exactly what an emoji font in the stack exists to catch. It is also why MDN advises always ending a font list with a generic family name, since no specific font is guaranteed to be installed. Naming a known emoji family, such as the openly licensed Noto Color Emoji which is built to cover the current Unicode emoji specification, gives the browser somewhere sensible to fall through to instead of reaching for .notdef.
Failure three: the print or PDF path swaps the font
This is the one that catches people out, because everything looks perfect on screen. Colour emoji are not stored in a single standard format. There are four rival ones in circulation: sbix from Apple, CBDT and CBLC from Google, COLR and CPAL from Microsoft, and SVG in OpenType. Support varies by application. Chrome handles CBDT and COLR but not SVG in OpenType, while Safari and Edge support sbix. A colour font may need to be supplied in several formats to work everywhere, which is precisely why the same emoji can be full colour in one place, monochrome in another and blank in a third.
The symptoms follow from that. People have reported emoji rendering in full colour in Chrome and then printing to PDF as hollow white outlines, with the print stylesheet apparently selecting a different font. In desktop publishing the failure is uglier still: exporting artwork set in Apple Color Emoji from InDesign has produced black squares around every emoji, because the only colour OpenType format Adobe officially supports is OpenType SVG. Copying a transcript into a word processor and exporting from there runs straight into the same mismatch.
There is a size trap too. Printing colour emoji from Chrome has been documented as a pathological case for its printing code, producing enormously large PDF files. A long, emoji heavy chat can therefore turn into a PDF far bigger than the text alone would suggest. If you are making a keepsake as described in How to Turn a WhatsApp Chat into a Printable PDF Keepsake, it is worth checking the file size before you send it anywhere.
The practical answer is to treat print as a separate rendering path and test it separately. Name a real emoji font in the print styles as well as the screen styles rather than assuming the browser will carry the screen choice over.
Variation selectors and joined sequences
Plenty of emoji are not single characters at all. Unicode's emoji standard defines U+FE0F, the variation selector that requests emoji presentation rather than plain text presentation, and zero width joiner sequences that stitch several code points into one picture. The man detective, for example, is U+1F575 followed by U+FE0F, then U+200D, then U+2642 and U+FE0F again. The five skin tone modifiers introduced in Unicode 8.0, based on the Fitzpatrick scale, follow a base emoji in the same way.
Variation selectors are invisible combining characters. They carry no shape of their own and simply tell the renderer which variant of the preceding character to draw. If software fails to consume one properly, you can end up with an unexpected extra box sitting next to an otherwise fine symbol. If a font or renderer does not support a joiner sequence, the parts can appear separately, so a single family emoji becomes several individual figures. In both cases the text itself is completely intact; only the drawing has gone wrong.
CSS offers font-variant-emoji for nudging presentation, where text renders as if U+FE0E were present and emoji as if U+FE0F were. It only affects characters listed as contributing to a Unicode emoji presentation sequence, so it will not rescue a character the font genuinely lacks. It is a tuning knob, not a repair tool.
Check the print dialogue before you blame the file
One last setting sits outside anything a stylesheet can control. MDN notes that any options a browser gives the user for controlling colour and images take priority over the print-color-adjust property, so there is no guarantee it does anything, and each browser handles it differently. In practice that means the "background graphics" tick box in the print dialogue. Leave it off and you will get a plainer page than intended, with message bubbles losing their tint. Turn it on before printing or saving to PDF. The general approach to getting a tidy page is covered in How to Print a WhatsApp Conversation.
What cannot be fixed
Some boxes are permanent, and it is only fair to say so. Exports from roughly 2012 and 2013 can contain legacy private use code points from the pre Unicode 6.0 iOS era, where a disappointed face was stored as U+E058 rather than today's U+1F61E. A fresh export of the same emoji uses the modern code point, but an archived old file still holds the old one, and no current emoji font maps it. Those characters may simply never render.
More broadly, no viewer can conjure content that was never in the file. Deleted messages are gone, an iCloud or Google Drive backup cannot be opened or read as a chat, and anything WhatsApp trimmed out before writing the export is not recoverable afterwards, which is worth understanding before you export a very long chat. WhatsApp Export Size Limit explains where those caps bite, and How to Export a WhatsApp Chat covers making the export in the first place. Emoji boxes are a rendering problem with a fix. Missing messages are not.
Ready to save yours? SaveMyChats turns a WhatsApp export into a beautiful web page or PDF — right in your browser, with nothing uploaded. Open SaveMyChats →