Recurring emoji corruption in production where Unicode characters (like ✓, 🎯, 🏌) appear as � (unknown character symbols) despite rendering correctly in development.
The issue was caused by:
- Missing emoji-compatible font fallbacks
- Lack of explicit UTF-8 content-type declarations
- No Unicode normalization for emoji characters
- Missing font-variant-emoji CSS properties
HTML Head (index.html):
<meta charset="UTF-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />Global CSS (client/global.css):
body {
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
* {
text-rendering: optimizeLegibility;
}Updated font fallback chain in both CSS and Tailwind config:
font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
"Noto Color Emoji";Key emoji fonts included:
"Apple Color Emoji"- iOS/macOS emoji support"Segoe UI Emoji"- Windows emoji support"Segoe UI Symbol"- Windows symbol fallback"Noto Color Emoji"- Android/Linux emoji support
CSS Properties for emoji handling:
.emoji,
[data-emoji="true"],
*:not(input):not(textarea) {
font-variant-emoji: emoji;
}JavaScript Unicode normalization utility (client/lib/emoji.ts):
export function safeEmoji(text: string): string {
return text.normalize("NFC"); // Canonical normalization
}Vite build process preserves Unicode:
- No additional configuration needed
- UTF-8 charset ensures proper encoding during build
- Font fallbacks prevent rendering issues
Fixed corrupted checkmark in leaderboard:
- Before:
✓ Database tables are set up correctly(corrupted) - After:
✓ Database tables are set up correctly(clean Unicode)
client/lib/emoji.ts provides:
EMOJIconstants for consistent emoji usagesafeEmoji()function for Unicode normalizationemojiStylesobject for inline emoji stylinggetStatusEmoji()helper for common status indicators
- Use the emoji constants: Import from
client/lib/emoji.ts - Normalize emoji text: Wrap emoji strings with
safeEmoji() - Test on multiple platforms: Verify emoji render on Windows, macOS, iOS, Android
- Monitor font loading: Ensure emoji fonts load correctly
- Test builds: Verify emoji preservation through minification
- Check encoding: Confirm UTF-8 headers are served correctly
The implemented solution provides emoji support for:
- ✅ iOS Safari - Apple Color Emoji
- ✅ macOS Safari/Chrome - Apple Color Emoji
- ✅ Windows Chrome/Edge - Segoe UI Emoji
- ✅ Android Chrome - Noto Color Emoji
- ✅ Linux browsers - Noto Color Emoji fallback
- Build process ✅ - No emoji corruption during minification
- Font fallbacks ✅ - Multiple emoji font options available
- UTF-8 encoding ✅ - Proper charset declarations
- Unicode normalization ✅ - Consistent character representation
To prevent future emoji corruption:
- Use emoji constants from the utility library
- Apply
safeEmoji()normalization for user-generated content - Test emoji rendering across different operating systems
- Monitor production for Unicode-related issues
The emoji corruption issue should now be resolved across all platforms and build environments.