A few months ago I needed to decode a Wingdings message. I went looking for an online tool, found several, and every single one only supported Wingdings 1. The message I was trying to decode was in Wingdings 2.
So I built my own: wingding-translator.net](https://wingding-translator.net)**
Here's what I learned along the way — some of it genuinely surprised me.
What Even Is Wingdings?
Wingdings is a symbol font created by Microsoft in 1990, designed by typeface designers Charles Bigelow and Kris Holmes. Instead of displaying letters when you type, it maps each keystroke to a visual symbol — arrows, hands, stars, zodiac signs, religious icons.
Microsoft released four variants total:
| Font | Character Set |
|---|---|
| Wingdings 1 | Hands, arrows, stars, zodiac, religious symbols |
| Wingdings 2 | Checkboxes, geometric shapes, circled numbers |
| Wingdings 3 | Directional arrows, keytop symbols |
| Webdings | Modern icons — planes, folders, smiley faces |
Each one maps keyboard characters to a completely different set of symbols. That's where the complexity starts.
The Unicode Problem
You'd think converting Wingdings to Unicode would be a simple lookup table. For Wingdings 1, mostly yes. For the others — not quite.
Problem 1: Incomplete Unicode coverage
Not every Wingdings symbol has a direct Unicode equivalent. Some obscure characters in Wingdings 2 and 3 required finding the nearest visual match in Unicode's Miscellaneous Symbols and Dingbats blocks. This is a judgement call, and different tools make different choices, which is why you'll sometimes get inconsistent output across translators.
Problem 2: Bidirectional decoding requires reverse lookup tables
Encoding (text → symbols) is straightforward. Decoding (symbols → text) requires reversing the map. The problem: some Unicode symbols map back to multiple possible Wingdings characters depending on which font variant was used. You need collision handling logic to pick the most likely match.
Problem 3: Mobile Unicode rendering is inconsistent
Some less common Unicode characters in the Wingdings 3 range render as empty boxes on older Android versions. The fix was detecting the user agent and either substituting a fallback or flagging the character visually so users know it's a rendering issue, not a translation error.
The OCR Feature
The most-requested feature after launch was: "Can I upload a screenshot and decode the Wingdings in it?"
This turned out to be the most interesting engineering problem. The requirement was that it had to be client-side only — no server uploads, for privacy. The solution was Tesseract.js, a pure JavaScript port of the Tesseract OCR engine.
The catch: Tesseract isn't trained on Wingdings by default. The workaround was to render the uploaded image using the actual Wingdings font via a canvas element, extract the character positions, then match each rendered glyph against the known Wingdings character map visually. It's not perfect for very small or low-contrast images, but it handles clean screenshots reliably.
The Undertale Audience
I didn't plan for this, but a significant chunk of users come from the Undertale community. In the game, the mysterious character W.D. Gaster communicates entirely in Wingdings. Players want to decode his messages and write fan content in his "language."
The critical detail: Gaster's font uses uppercase only. Typing in lowercase gives you a completely different symbol set. Most translators don't document this clearly, which causes a lot of confusion. I added a prominent note and an ALL CAPS toggle specifically for this use case.
If you're targeting this audience, the search terms are: "undertale wingdings translator", "gaster translator", "wd gaster font". High volume, underserved by most tools.
What I'd Do Differently
Use a static site, not WordPress. The LiteSpeed + WordPress stack is solid for content sites but overkill for a single-tool utility. The overhead adds unnecessary complexity — cache invalidation, plugin conflicts, update management. A simple static HTML/JS/CSS deployment would have been faster to build, faster to load, and easier to maintain.
Build the Gaster page first. The Undertale community is enormous and actively searches for this tool. It should have been page one, not an afterthought.
Add shareable URLs from day one. Letting users generate a permalink like wingding-translator.net/?text=hello makes the tool inherently shareable. Every shared link is a backlink. I added this later — it should have been in v1.
Try It
If you need to translate or decode Wingdings, the tool is free and requires no signup:
Supports Wingdings 1, 2, 3, Webdings, real-time bidirectional translation, OCR image decode, and image download. Nothing is stored server-side.
Happy to answer questions about the Unicode mapping approach or the Tesseract implementation in the comments.
Tags: webdev, javascript, showdev, tools
Top comments (0)